diff --git a/CHANGELOG.md b/CHANGELOG.md index 28b47fe20..b049c6a91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ### Release Notes: +- Telegraf now keeps a fixed-length buffer of metrics per-output. This buffer +defaults to 10,000 metrics, and is adjustable. The buffer is cleared when a +successful write to that output occurs. - The docker plugin has been significantly overhauled to add more metrics and allow for docker-machine (incl OSX) support. [See the readme](https://github.com/influxdata/telegraf/blob/master/plugins/inputs/docker/README.md) @@ -26,6 +29,11 @@ specifying a docker endpoint to get metrics from. - [#553](https://github.com/influxdata/telegraf/pull/553): Amazon CloudWatch output. thanks @skwong2! - [#503](https://github.com/influxdata/telegraf/pull/503): Support docker endpoint configuration. - [#563](https://github.com/influxdata/telegraf/pull/563): Docker plugin overhaul. +- [#285](https://github.com/influxdata/telegraf/issues/285): Fixed-size buffer of points. +- [#546](https://github.com/influxdata/telegraf/pull/546): SNMP Input plugin. Thanks @titilambert! +- [#589](https://github.com/influxdata/telegraf/pull/589): Microsoft SQL Server input plugin. Thanks @zensqlmonitor! +- [#573](https://github.com/influxdata/telegraf/pull/573): Github webhooks consumer input. Thanks @jackzampolin! +- [#471](https://github.com/influxdata/telegraf/pull/471): httpjson request headers. Thanks @asosso! ### Bugfixes - [#506](https://github.com/influxdata/telegraf/pull/506): Ping input doesn't return response time metric when timeout. Thanks @titilambert! @@ -34,6 +42,8 @@ specifying a docker endpoint to get metrics from. - [#543](https://github.com/influxdata/telegraf/issues/543): Statsd Packet size sometimes truncated. - [#440](https://github.com/influxdata/telegraf/issues/440): Don't query filtered devices for disk stats. - [#463](https://github.com/influxdata/telegraf/issues/463): Docker plugin not working on AWS Linux +- [#568](https://github.com/influxdata/telegraf/issues/568): Multiple output race condition. +- [#585](https://github.com/influxdata/telegraf/pull/585): Log stack trace and continue on Telegraf panic. Thanks @wutaizeng! ## v0.10.0 [2016-01-12] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f7e2ec86f..1dad3ab17 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,10 +1,16 @@ ## Steps for Contributing: -1. [Sign the CLA](https://github.com/influxdata/telegraf/blob/master/CONTRIBUTING.md#sign-the-cla) -1. Write your input or output plugin (see below for details) +1. [Sign the CLA](http://influxdb.com/community/cla.html) +1. Make changes or write plugin (see below for details) 1. Add your plugin to `plugins/inputs/all/all.go` or `plugins/outputs/all/all.go` 1. If your plugin requires a new Go package, [add it](https://github.com/influxdata/telegraf/blob/master/CONTRIBUTING.md#adding-a-dependency) +1. Write a README for your plugin, if it's an input plugin, it should be structured +like the [input example here](https://github.com/influxdata/telegraf/blob/master/plugins/inputs/EXAMPLE_README.md). +Output plugins READMEs are less structured, +but any information you can provide on how the data will look is appreciated. +See the [OpenTSDB output](https://github.com/influxdata/telegraf/tree/master/plugins/outputs/opentsdb) +for a good example. ## Sign the CLA @@ -13,9 +19,10 @@ which can be found [on our website](http://influxdb.com/community/cla.html) ## Adding a dependency -Assuming you can already build the project: +Assuming you can already build the project, run these in the telegraf directory: 1. `go get github.com/sparrc/gdm` +1. `gdm restore` 1. `gdm save` ## Input Plugins diff --git a/Godeps b/Godeps index 9f46fd79b..3393a1cee 100644 --- a/Godeps +++ b/Godeps @@ -3,27 +3,30 @@ github.com/Shopify/sarama d37c73f2b2bce85f7fa16b6a550d26c5372892ef github.com/Sirupsen/logrus f7f79f729e0fbe2fcc061db48a9ba0263f588252 github.com/amir/raidman 6a8e089bbe32e6b907feae5ba688841974b3c339 github.com/armon/go-metrics 345426c77237ece5dab0e1605c3e4b35c3f54757 -github.com/aws/aws-sdk-go 3ad0b07b44c22c21c734d1094981540b7a11e942 +github.com/aws/aws-sdk-go 87b1e60a50b09e4812dee560b33a238f67305804 github.com/beorn7/perks b965b613227fddccbfffe13eae360ed3fa822f8d -github.com/boltdb/bolt 6465994716bf6400605746e79224cf1e7ed68725 +github.com/boltdb/bolt ee4a0888a9abe7eefe5a0992ca4cb06864839873 github.com/cenkalti/backoff 4dc77674aceaabba2c7e3da25d4c823edfb73f99 -github.com/dancannon/gorethink ff457cac6a529d9749d841a733d76e8305cba3c8 +github.com/dancannon/gorethink 6f088135ff288deb9d5546f4c71919207f891a70 github.com/davecgh/go-spew 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d github.com/eapache/go-resiliency b86b1ec0dd4209a588dc1285cdd471e73525c0b3 github.com/eapache/queue ded5959c0d4e360646dc9e9908cff48666781367 -github.com/fsouza/go-dockerclient 6fb38e6bb3d544d7eb5b55fd396cd4e6850802d8 +github.com/fsouza/go-dockerclient 7b651349f9479f5114913eefbfd3c4eeddd79ab4 github.com/go-ini/ini afbd495e5aaea13597b5e14fe514ddeaa4d76fc3 -github.com/go-sql-driver/mysql 72ea5d0b32a04c67710bf63e97095d82aea5f352 -github.com/gogo/protobuf c57e439bad574c2e0877ff18d514badcfced004d -github.com/golang/protobuf 2402d76f3d41f928c7902a765dfc872356dd3aad +github.com/go-sql-driver/mysql 7c7f556282622f94213bc028b4d0a7b6151ba239 +github.com/gogo/protobuf e8904f58e872a473a5b91bc9bf3377d223555263 +github.com/golang/protobuf 6aaa8d47701fa6cf07e914ec01fde3d4a1fe79c3 github.com/golang/snappy 723cc1e459b8eea2dea4583200fd60757d40097a github.com/gonuts/go-shellquote e842a11b24c6abfb3dd27af69a17f482e4b483c2 -github.com/hailocab/go-hostpool 50839ee41f32bfca8d03a183031aa634b2dc1c64 +github.com/gorilla/context 1c83b3eabd45b6d76072b66b746c20815fb2872d +github.com/gorilla/mux 26a6070f849969ba72b72256e9f14cf519751690 +github.com/hailocab/go-hostpool e80d13ce29ede4452c43dea11e79b9bc8a15b478 github.com/hashicorp/go-msgpack fa3f63826f7c23912c15263591e65d54d080b458 -github.com/hashicorp/raft b95f335efee1992886864389183ebda0c0a5d0f6 +github.com/hashicorp/raft 057b893fd996696719e98b6c44649ea14968c811 github.com/hashicorp/raft-boltdb d1e82c1ec3f15ee991f7cc7ffd5b67ff6f5bbaee -github.com/influxdata/influxdb 0e0f85a0c1fd1788ae4f9145531b02c539cfa5b5 -github.com/influxdb/influxdb 0e0f85a0c1fd1788ae4f9145531b02c539cfa5b5 +github.com/influxdata/config bae7cb98197d842374d3b8403905924094930f24 +github.com/influxdata/influxdb 697f48b4e62e514e701ffec39978b864a3c666e6 +github.com/influxdb/influxdb 697f48b4e62e514e701ffec39978b864a3c666e6 github.com/jmespath/go-jmespath c01cf91b011868172fdcd9f41838e80c9d716264 github.com/klauspost/crc32 999f3125931f6557b991b2f8472172bdfa578d38 github.com/lib/pq 8ad2b298cadd691a77015666a5372eae5dbfac8f @@ -36,19 +39,21 @@ github.com/pborman/uuid dee7705ef7b324f27ceb85a121c61f2c2e8ce988 github.com/pmezard/go-difflib 792786c7400a136282c1664665ae0a8db921c6c2 github.com/prometheus/client_golang 67994f177195311c3ea3d4407ed0175e34a4256f github.com/prometheus/client_model fa8ad6fec33561be4280a8f0514318c79d7f6cb6 -github.com/prometheus/common 0a3005bb37bc411040083a55372e77c405f6464c +github.com/prometheus/common 14ca1097bbe21584194c15e391a9dab95ad42a59 github.com/prometheus/procfs 406e5b7bfd8201a36e2bb5f7bdae0b03380c2ce8 github.com/samuel/go-zookeeper 218e9c81c0dd8b3b18172b2bbfad92cc7d6db55f -github.com/shirou/gopsutil 8850f58d7035653e1ab90711481954c8ca1b9813 +github.com/shirou/gopsutil 85bf0974ed06e4e668595ae2b4de02e772a2819b +github.com/soniah/gosnmp b1b4f885b12c5dcbd021c5cee1c904110de6db7d github.com/streadway/amqp b4f3ceab0337f013208d31348b578d83c0064744 github.com/stretchr/objx 1a9d0bb9f541897e62256577b352fdbc1fb4fd94 github.com/stretchr/testify f390dcf405f7b83c997eac1b06768bb9f44dec18 github.com/wvanbergen/kafka 1a8639a45164fcc245d5c7b4bd3ccfbd1a0ffbf3 github.com/wvanbergen/kazoo-go 0f768712ae6f76454f987c3356177e138df258f8 -golang.org/x/crypto 3760e016850398b85094c4c99e955b8c3dea5711 -golang.org/x/net 72aa00c6241a8013dc9b040abb45f57edbe73945 -golang.org/x/text cf4986612c83df6c55578ba198316d1684a9a287 -gopkg.in/dancannon/gorethink.v1 e2cef022d0495329dfb0635991de76efcab5cf50 +github.com/zensqlmonitor/go-mssqldb ffe5510c6fa5e15e6d983210ab501c815b56b363 +golang.org/x/crypto 1f22c0103821b9390939b6776727195525381532 +golang.org/x/net 04b9de9b512f58addf28c9853d50ebef61c3953e +golang.org/x/text 6d3c22c4525a4da167968fa2479be5524d2e8bd0 +gopkg.in/dancannon/gorethink.v1 6f088135ff288deb9d5546f4c71919207f891a70 gopkg.in/fatih/pool.v2 cba550ebf9bce999a02e963296d4bc7a486cb715 gopkg.in/mgo.v2 03c9f3ee4c14c8e51ee521a6a7d0425658dd6f64 gopkg.in/yaml.v2 f7716cbe52baa25d2e9b0d0da546fcf909fc16b4 diff --git a/Makefile b/Makefile index 3dedfb703..9e62cd900 100644 --- a/Makefile +++ b/Makefile @@ -52,6 +52,7 @@ endif docker run --name nsq -p "4150:4150" -d nsqio/nsq /nsqd docker run --name mqtt -p "1883:1883" -d ncarlier/mqtt docker run --name riemann -p "5555:5555" -d blalor/riemann + docker run --name snmp -p "31161:31161/udp" -d titilambert/snmpsim # Run docker containers necessary for CircleCI unit tests docker-run-circle: @@ -65,11 +66,12 @@ docker-run-circle: docker run --name nsq -p "4150:4150" -d nsqio/nsq /nsqd docker run --name mqtt -p "1883:1883" -d ncarlier/mqtt docker run --name riemann -p "5555:5555" -d blalor/riemann + docker run --name snmp -p "31161:31161/udp" -d titilambert/snmpsim # Kill all docker containers, ignore errors docker-kill: - -docker kill nsq aerospike redis opentsdb rabbitmq postgres memcached mysql kafka mqtt riemann - -docker rm nsq aerospike redis opentsdb rabbitmq postgres memcached mysql kafka mqtt riemann + -docker kill nsq aerospike redis opentsdb rabbitmq postgres memcached mysql kafka mqtt riemann snmp + -docker rm nsq aerospike redis opentsdb rabbitmq postgres memcached mysql kafka mqtt riemann snmp # Run full unit tests using docker containers (includes setup and teardown) test: docker-kill docker-run diff --git a/README.md b/README.md index 7207db8a9..59e987247 100644 --- a/README.md +++ b/README.md @@ -164,10 +164,12 @@ Currently implemented sources: * rabbitmq * redis * rethinkdb +* sql server (microsoft) * twemproxy * zfs * zookeeper * sensors +* snmp * system * cpu * mem @@ -181,6 +183,7 @@ Telegraf can also collect metrics via the following service plugins: * statsd * kafka_consumer +* github_webhooks We'll be adding support for many more over the coming months. Read on if you want to add support for another service or third-party API. diff --git a/accumulator.go b/accumulator.go index c628907d7..83f61ae99 100644 --- a/accumulator.go +++ b/accumulator.go @@ -7,7 +7,7 @@ import ( "sync" "time" - "github.com/influxdata/telegraf/internal/config" + "github.com/influxdata/telegraf/internal/models" "github.com/influxdata/influxdb/client/v2" ) @@ -29,7 +29,7 @@ type Accumulator interface { } func NewAccumulator( - inputConfig *config.InputConfig, + inputConfig *models.InputConfig, points chan *client.Point, ) Accumulator { acc := accumulator{} @@ -47,7 +47,7 @@ type accumulator struct { debug bool - inputConfig *config.InputConfig + inputConfig *models.InputConfig prefix string } diff --git a/agent.go b/agent.go index 5425fba33..ee5f45029 100644 --- a/agent.go +++ b/agent.go @@ -7,10 +7,12 @@ import ( "math/big" "math/rand" "os" + "runtime" "sync" "time" "github.com/influxdata/telegraf/internal/config" + "github.com/influxdata/telegraf/internal/models" "github.com/influxdata/telegraf/plugins/inputs" "github.com/influxdata/telegraf/plugins/outputs" @@ -86,6 +88,18 @@ func (a *Agent) Close() error { return err } +func panicRecover(input *models.RunningInput) { + if err := recover(); err != nil { + trace := make([]byte, 2048) + runtime.Stack(trace, true) + log.Printf("FATAL: Input [%s] panicked: %s, Stack:\n%s\n", + input.Name, err, trace) + log.Println("PLEASE REPORT THIS PANIC ON GITHUB with " + + "stack trace, configuration, and OS information: " + + "https://github.com/influxdata/telegraf/issues/new") + } +} + // gatherParallel runs the inputs that are using the same reporting interval // as the telegraf agent. func (a *Agent) gatherParallel(pointChan chan *client.Point) error { @@ -101,7 +115,8 @@ func (a *Agent) gatherParallel(pointChan chan *client.Point) error { wg.Add(1) counter++ - go func(input *config.RunningInput) { + go func(input *models.RunningInput) { + defer panicRecover(input) defer wg.Done() acc := NewAccumulator(input.Config, pointChan) @@ -144,9 +159,11 @@ func (a *Agent) gatherParallel(pointChan chan *client.Point) error { // reporting interval. func (a *Agent) gatherSeparate( shutdown chan struct{}, - input *config.RunningInput, + input *models.RunningInput, pointChan chan *client.Point, ) error { + defer panicRecover(input) + ticker := time.NewTicker(input.Config.Interval) for { @@ -202,7 +219,6 @@ func (a *Agent) Test() error { for _, input := range a.Config.Inputs { acc := NewAccumulator(input.Config, pointChan) acc.SetDebug(true) - // acc.SetPrefix(input.Name + "_") fmt.Printf("* Plugin: %s, Collection 1\n", input.Name) if input.Config.Interval != 0 { @@ -228,93 +244,45 @@ func (a *Agent) Test() error { return nil } -// writeOutput writes a list of points to a single output, with retries. -// Optionally takes a `done` channel to indicate that it is done writing. -func (a *Agent) writeOutput( - points []*client.Point, - ro *config.RunningOutput, - shutdown chan struct{}, - wg *sync.WaitGroup, -) { - defer wg.Done() - if len(points) == 0 { - return - } - retry := 0 - retries := a.Config.Agent.FlushRetries - start := time.Now() - - for { - filtered := ro.FilterPoints(points) - err := ro.Output.Write(filtered) - if err == nil { - // Write successful - elapsed := time.Since(start) - if !a.Config.Agent.Quiet { - log.Printf("Flushed %d metrics to output %s in %s\n", - len(filtered), ro.Name, elapsed) - } - return - } - - select { - case <-shutdown: - return - default: - if retry >= retries { - // No more retries - msg := "FATAL: Write to output [%s] failed %d times, dropping" + - " %d metrics\n" - log.Printf(msg, ro.Name, retries+1, len(points)) - return - } else if err != nil { - // Sleep for a retry - log.Printf("Error in output [%s]: %s, retrying in %s", - ro.Name, err.Error(), a.Config.Agent.FlushInterval.Duration) - time.Sleep(a.Config.Agent.FlushInterval.Duration) - } - } - - retry++ - } -} - // flush writes a list of points to all configured outputs -func (a *Agent) flush( - points []*client.Point, - shutdown chan struct{}, - wait bool, -) { +func (a *Agent) flush() { var wg sync.WaitGroup + + wg.Add(len(a.Config.Outputs)) for _, o := range a.Config.Outputs { - wg.Add(1) - go a.writeOutput(points, o, shutdown, &wg) - } - if wait { - wg.Wait() + go func(output *models.RunningOutput) { + defer wg.Done() + err := output.Write() + if err != nil { + log.Printf("Error writing to output [%s]: %s\n", + output.Name, err.Error()) + } + }(o) } + + wg.Wait() } // flusher monitors the points input channel and flushes on the minimum interval func (a *Agent) flusher(shutdown chan struct{}, pointChan chan *client.Point) error { // Inelegant, but this sleep is to allow the Gather threads to run, so that // the flusher will flush after metrics are collected. - time.Sleep(time.Millisecond * 100) + time.Sleep(time.Millisecond * 200) ticker := time.NewTicker(a.Config.Agent.FlushInterval.Duration) - points := make([]*client.Point, 0) for { select { case <-shutdown: log.Println("Hang on, flushing any cached points before shutdown") - a.flush(points, shutdown, true) + a.flush() return nil case <-ticker.C: - a.flush(points, shutdown, false) - points = make([]*client.Point, 0) + a.flush() case pt := <-pointChan: - points = append(points, pt) + for _, o := range a.Config.Outputs { + o.AddPoint(pt) + } } } } @@ -389,7 +357,7 @@ func (a *Agent) Run(shutdown chan struct{}) error { // configured. Default intervals are handled below with gatherParallel if input.Config.Interval != 0 { wg.Add(1) - go func(input *config.RunningInput) { + go func(input *models.RunningInput) { defer wg.Done() if err := a.gatherSeparate(shutdown, input, pointChan); err != nil { log.Printf(err.Error()) diff --git a/build.py b/build.py index a5892f26a..8efc1e22d 100755 --- a/build.py +++ b/build.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python # # This is the Telegraf build script. # @@ -17,11 +17,7 @@ import tempfile import hashlib import re -try: - import boto - from boto.s3.key import Key -except ImportError: - pass +debug = False # PACKAGING VARIABLES INSTALL_ROOT_DIR = "/usr/bin" @@ -73,12 +69,10 @@ targets = { } supported_builds = { - # TODO(rossmcdonald): Add support for multiple GOARM values - 'darwin': [ "amd64", "386" ], - # 'windows': [ "amd64", "386", "arm", "arm64" ], - 'linux': [ "amd64", "386", "arm" ] + 'darwin': [ "amd64", "i386" ], + 'windows': [ "amd64", "i386", "arm" ], + 'linux': [ "amd64", "i386", "arm" ] } -supported_go = [ '1.5.1' ] supported_packages = { "darwin": [ "tar", "zip" ], "linux": [ "deb", "rpm", "tar", "zip" ], @@ -87,6 +81,8 @@ supported_packages = { def run(command, allow_failure=False, shell=False): out = None + if debug: + print("[DEBUG] {}".format(command)) try: if shell: out = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=shell) @@ -122,8 +118,11 @@ def run(command, allow_failure=False, shell=False): else: return out -def create_temp_dir(): - return tempfile.mkdtemp(prefix="telegraf-build.") +def create_temp_dir(prefix=None): + if prefix is None: + return tempfile.mkdtemp(prefix="telegraf-build.") + else: + return tempfile.mkdtemp(prefix=prefix) def get_current_version(): command = "git describe --always --tags --abbrev=0" @@ -185,31 +184,44 @@ def check_environ(build_dir = None): def check_prereqs(): print("\nChecking for dependencies:") for req in prereqs: - print("\t- {} ->".format(req),) path = check_path_for(req) - if path: - print("{}".format(path)) - else: - print("?") + if path is None: + path = '?' + print("\t- {} -> {}".format(req, path)) for req in optional_prereqs: - print("\t- {} (optional) ->".format(req)) path = check_path_for(req) - if path: - print("{}".format(path)) - else: - print("?") + if path is None: + path = '?' + print("\t- {} (optional) -> {}".format(req, path)) print("") -def upload_packages(packages, nightly=False): +def upload_packages(packages, bucket_name=None, nightly=False): + if debug: + print("[DEBUG] upload_packags: {}".format(packages)) + try: + import boto + from boto.s3.key import Key + except ImportError: + print "!! Cannot upload packages without the 'boto' python library." + return 1 print("Uploading packages to S3...") print("") c = boto.connect_s3() - # TODO(rossmcdonald) - Set to different S3 bucket for release vs nightly - bucket = c.get_bucket('get.influxdb.org') + if bucket_name is None: + bucket_name = 'get.influxdb.org/telegraf' + bucket = c.get_bucket(bucket_name.split('/')[0]) + print("\t - Using bucket: {}".format(bucket_name)) for p in packages: - name = os.path.join('telegraf', os.path.basename(p)) + if '/' in bucket_name: + # Allow for nested paths within the bucket name (ex: + # bucket/telegraf). Assuming forward-slashes as path + # delimiter. + name = os.path.join('/'.join(bucket_name.split('/')[1:]), + os.path.basename(p)) + else: + name = os.path.basename(p) if bucket.get_key(name) is None or nightly: - print("\t - Uploading {}...".format(name)) + print("\t - Uploading {} to {}...".format(name, bucket_name)) k = Key(bucket) k.key = name if nightly: @@ -217,7 +229,6 @@ def upload_packages(packages, nightly=False): else: n = k.set_contents_from_filename(p, replace=False) k.make_public() - print("[ DONE ]") else: print("\t - Not uploading {}, already exists.".format(p)) print("") @@ -227,7 +238,6 @@ def run_tests(race, parallel, timeout, no_vet): print("Retrieving Go dependencies...") sys.stdout.flush() run(get_command) - print("done.") print("Running tests:") print("\tRace: ", race) if parallel is not None: @@ -307,9 +317,15 @@ def build(version=None, # If a release candidate, update the version information accordingly version = "{}rc{}".format(version, rc) + # Set architecture to something that Go expects + if arch == 'i386': + arch = '386' + elif arch == 'x86_64': + arch = 'amd64' + print("Starting build...") for b, c in targets.items(): - print("\t- Building '{}'...".format(os.path.join(outdir, b)),) + print("\t- Building '{}'...".format(os.path.join(outdir, b))) build_command = "" build_command += "GOOS={} GOARCH={} ".format(platform, arch) if arch == "arm" and goarm_version: @@ -323,16 +339,15 @@ def build(version=None, if "1.4" in go_version: build_command += "-ldflags=\"-X main.buildTime '{}' ".format(datetime.datetime.utcnow().isoformat()) build_command += "-X main.Version {} ".format(version) - build_command += "-X main.Branch {} ".format(branch) + build_command += "-X main.Branch {} ".format(get_current_branch()) build_command += "-X main.Commit {}\" ".format(get_current_commit()) else: build_command += "-ldflags=\"-X main.buildTime='{}' ".format(datetime.datetime.utcnow().isoformat()) build_command += "-X main.Version={} ".format(version) - build_command += "-X main.Branch={} ".format(branch) + build_command += "-X main.Branch={} ".format(get_current_branch()) build_command += "-X main.Commit={}\" ".format(get_current_commit()) build_command += c run(build_command, shell=True) - print("[ DONE ]") print("") def create_dir(path): @@ -386,7 +401,6 @@ def go_get(update=False): get_command = "go get -d ./..." print("Retrieving Go dependencies...") run(get_command) - print("done.\n") def generate_md5_from_file(path): m = hashlib.md5() @@ -401,6 +415,8 @@ def generate_md5_from_file(path): def build_packages(build_output, version, nightly=False, rc=None, iteration=1): outfiles = [] tmp_build_dir = create_temp_dir() + if debug: + print("[DEBUG] build_output = {}".format(build_output)) try: print("-------------------------") print("") @@ -429,18 +445,24 @@ def build_packages(build_output, version, nightly=False, rc=None, iteration=1): for package_type in supported_packages[p]: print("\t- Packaging directory '{}' as '{}'...".format(build_root, package_type)) name = "telegraf" + # Reset version, iteration, and current location on each run + # since they may be modified below. package_version = version package_iteration = iteration + current_location = build_output[p][a] + if package_type in ['zip', 'tar']: if nightly: name = '{}-nightly_{}_{}'.format(name, p, a) else: - name = '{}-{}_{}_{}'.format(name, version, p, a) + name = '{}-{}-{}_{}_{}'.format(name, package_version, package_iteration, p, a) if package_type == 'tar': # Add `tar.gz` to path to reduce package size current_location = os.path.join(current_location, name + '.tar.gz') if rc is not None: package_iteration = "0.rc{}".format(rc) + if a == '386': + a = 'i386' fpm_command = "fpm {} --name {} -a {} -t {} --version {} --iteration {} -C {} -p {} ".format( fpm_common_args, name, @@ -465,10 +487,11 @@ def build_packages(build_output, version, nightly=False, rc=None, iteration=1): if nightly and package_type in ['deb', 'rpm']: outfile = rename_file(outfile, outfile.replace("{}-{}".format(version, iteration), "nightly")) outfiles.append(os.path.join(os.getcwd(), outfile)) - print("[ DONE ]") # Display MD5 hash for generated package print("\t\tMD5 = {}".format(generate_md5_from_file(outfile))) print("") + if debug: + print("[DEBUG] package outfiles: {}".format(outfiles)) return outfiles finally: # Cleanup @@ -495,6 +518,9 @@ def print_usage(): print("\t --parallel \n\t\t- Run Go tests in parallel up to the count specified.") print("\t --timeout \n\t\t- Timeout for Go tests. Defaults to 480s.") print("\t --clean \n\t\t- Clean the build output directory prior to creating build.") + print("\t --no-get \n\t\t- Do not run `go get` before building.") + print("\t --bucket=\n\t\t- Full path of the bucket to upload packages to (must also specify --upload).") + print("\t --debug \n\t\t- Displays debug output.") print("") def print_package_summary(packages): @@ -521,6 +547,9 @@ def main(): iteration = 1 no_vet = False goarm_version = "6" + run_get = True + upload_bucket = None + global debug for arg in sys.argv[1:]: if '--outdir' in arg: @@ -578,6 +607,14 @@ def main(): elif '--goarm' in arg: # Signifies GOARM flag to pass to build command when compiling for ARM goarm_version = arg.split("=")[1] + elif '--bucket' in arg: + # The bucket to upload the packages to, relies on boto + upload_bucket = arg.split("=")[1] + elif '--no-get' in arg: + run_get = False + elif '--debug' in arg: + print "[DEBUG] Using debug output" + debug = True elif '--help' in arg: print_usage() return 0 @@ -614,15 +651,19 @@ def main(): # If a release candidate or nightly, set iteration to 0 (instead of 1) iteration = 0 + if target_arch == '386': + target_arch = 'i386' + elif target_arch == 'x86_64': + target_arch = 'amd64' + build_output = {} - # TODO(rossmcdonald): Prepare git repo for build (checking out correct branch/commit, etc.) - # prepare(branch=branch, commit=commit) if test: if not run_tests(race, parallel, timeout, no_vet): return 1 return 0 - go_get(update=update) + if run_get: + go_get(update=update) platforms = [] single_build = True @@ -663,11 +704,9 @@ def main(): print("!! Cannot package without command 'fpm'. Stopping.") return 1 packages = build_packages(build_output, version, nightly=nightly, rc=rc, iteration=iteration) - # TODO(rossmcdonald): Add nice output for print_package_summary() - # print_package_summary(packages) # Optionally upload to S3 if upload: - upload_packages(packages, nightly=nightly) + upload_packages(packages, bucket_name=upload_bucket, nightly=nightly) return 0 if __name__ == '__main__': diff --git a/internal/config/config.go b/internal/config/config.go index 3b5e4ff17..5f97f8350 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -11,13 +11,12 @@ import ( "time" "github.com/influxdata/telegraf/internal" + "github.com/influxdata/telegraf/internal/models" "github.com/influxdata/telegraf/plugins/inputs" "github.com/influxdata/telegraf/plugins/outputs" - "github.com/naoina/toml" + "github.com/influxdata/config" "github.com/naoina/toml/ast" - - "github.com/influxdata/influxdb/client/v2" ) // Config specifies the URL/user/password for the database that telegraf @@ -29,8 +28,8 @@ type Config struct { OutputFilters []string Agent *AgentConfig - Inputs []*RunningInput - Outputs []*RunningOutput + Inputs []*models.RunningInput + Outputs []*models.RunningOutput } func NewConfig() *Config { @@ -40,13 +39,12 @@ func NewConfig() *Config { Interval: internal.Duration{Duration: 10 * time.Second}, RoundInterval: true, FlushInterval: internal.Duration{Duration: 10 * time.Second}, - FlushRetries: 2, FlushJitter: internal.Duration{Duration: 5 * time.Second}, }, Tags: make(map[string]string), - Inputs: make([]*RunningInput, 0), - Outputs: make([]*RunningOutput, 0), + Inputs: make([]*models.RunningInput, 0), + Outputs: make([]*models.RunningOutput, 0), InputFilters: make([]string, 0), OutputFilters: make([]string, 0), } @@ -70,15 +68,17 @@ type AgentConfig struct { // Interval at which to flush data FlushInterval internal.Duration - // FlushRetries is the number of times to retry each data flush - FlushRetries int - // FlushJitter Jitters the flush interval by a random amount. // This is primarily to avoid large write spikes for users running a large // number of telegraf instances. // ie, a jitter of 5s and interval 10s means flushes will happen every 10-15s FlushJitter internal.Duration + // MetricBufferLimit is the max number of metrics that each output plugin + // will cache. The buffer is cleared when a successful write occurs. When + // full, the oldest metrics will be overwritten. + MetricBufferLimit int + // TODO(cam): Remove UTC and Precision parameters, they are no longer // valid for the agent config. Leaving them here for now for backwards- // compatability @@ -93,129 +93,6 @@ type AgentConfig struct { Hostname string } -// TagFilter is the name of a tag, and the values on which to filter -type TagFilter struct { - Name string - Filter []string -} - -type RunningOutput struct { - Name string - Output outputs.Output - Config *OutputConfig -} - -type RunningInput struct { - Name string - Input inputs.Input - Config *InputConfig -} - -// Filter containing drop/pass and tagdrop/tagpass rules -type Filter struct { - Drop []string - Pass []string - - TagDrop []TagFilter - TagPass []TagFilter - - IsActive bool -} - -// InputConfig containing a name, interval, and filter -type InputConfig struct { - Name string - NameOverride string - MeasurementPrefix string - MeasurementSuffix string - Tags map[string]string - Filter Filter - Interval time.Duration -} - -// OutputConfig containing name and filter -type OutputConfig struct { - Name string - Filter Filter -} - -// Filter returns filtered slice of client.Points based on whether filters -// are active for this RunningOutput. -func (ro *RunningOutput) FilterPoints(points []*client.Point) []*client.Point { - if !ro.Config.Filter.IsActive { - return points - } - - var filteredPoints []*client.Point - for i := range points { - if !ro.Config.Filter.ShouldPass(points[i].Name()) || !ro.Config.Filter.ShouldTagsPass(points[i].Tags()) { - continue - } - filteredPoints = append(filteredPoints, points[i]) - } - return filteredPoints -} - -// ShouldPass returns true if the metric should pass, false if should drop -// based on the drop/pass filter parameters -func (f Filter) ShouldPass(fieldkey string) bool { - if f.Pass != nil { - for _, pat := range f.Pass { - // TODO remove HasPrefix check, leaving it for now for legacy support. - // Cam, 2015-12-07 - if strings.HasPrefix(fieldkey, pat) || internal.Glob(pat, fieldkey) { - return true - } - } - return false - } - - if f.Drop != nil { - for _, pat := range f.Drop { - // TODO remove HasPrefix check, leaving it for now for legacy support. - // Cam, 2015-12-07 - if strings.HasPrefix(fieldkey, pat) || internal.Glob(pat, fieldkey) { - return false - } - } - - return true - } - return true -} - -// ShouldTagsPass returns true if the metric should pass, false if should drop -// based on the tagdrop/tagpass filter parameters -func (f Filter) ShouldTagsPass(tags map[string]string) bool { - if f.TagPass != nil { - for _, pat := range f.TagPass { - if tagval, ok := tags[pat.Name]; ok { - for _, filter := range pat.Filter { - if internal.Glob(filter, tagval) { - return true - } - } - } - } - return false - } - - if f.TagDrop != nil { - for _, pat := range f.TagDrop { - if tagval, ok := tags[pat.Name]; ok { - for _, filter := range pat.Filter { - if internal.Glob(filter, tagval) { - return false - } - } - } - } - return true - } - - return true -} - // Inputs returns a list of strings of the configured inputs. func (c *Config) InputNames() []string { var name []string @@ -251,24 +128,14 @@ func (c *Config) ListTags() string { var header = `# Telegraf configuration # Telegraf is entirely plugin driven. All metrics are gathered from the -# declared inputs. +# declared inputs, and sent to the declared outputs. -# Even if a plugin has no configuration, it must be declared in here -# to be active. Declaring a plugin means just specifying the name -# as a section with no variables. To deactivate a plugin, comment -# out the name and any variables. +# Plugins must be declared in here to be active. +# To deactivate a plugin, comment out the name and any variables. -# Use 'telegraf -config telegraf.toml -test' to see what metrics a config +# Use 'telegraf -config telegraf.conf -test' to see what metrics a config # file would generate. -# One rule that plugins conform to is wherever a connection string -# can be passed, the values '' and 'localhost' are treated specially. -# They indicate to the plugin to use their own builtin configuration to -# connect to the local system. - -# NOTE: The configuration has a few required parameters. They are marked -# with 'required'. Be sure to edit those to make this configuration work. - # Tags can also be specified via a normal map, but only one form at a time: [tags] # dc = "us-east-1" @@ -280,6 +147,11 @@ var header = `# Telegraf configuration # Rounds collection interval to 'interval' # ie, if interval="10s" then always collect on :00, :10, :20, etc. round_interval = true + + # Telegraf will cache metric_buffer_limit metrics for each output, and will + # flush this buffer on a successful write. + metric_buffer_limit = 10000 + # Collection jitter is used to jitter the collection by a random amount. # Each plugin will sleep for a random time within jitter before collecting. # This can be used to avoid many plugins querying things like sysfs at the @@ -442,12 +314,7 @@ func (c *Config) LoadDirectory(path string) error { // LoadConfig loads the given config file and applies it to c func (c *Config) LoadConfig(path string) error { - data, err := ioutil.ReadFile(path) - if err != nil { - return err - } - - tbl, err := toml.Parse(data) + tbl, err := config.ParseFile(path) if err != nil { return err } @@ -460,12 +327,12 @@ func (c *Config) LoadConfig(path string) error { switch name { case "agent": - if err = toml.UnmarshalTable(subTable, c.Agent); err != nil { + if err = config.UnmarshalTable(subTable, c.Agent); err != nil { log.Printf("Could not parse [agent] config\n") return err } case "tags": - if err = toml.UnmarshalTable(subTable, c.Tags); err != nil { + if err = config.UnmarshalTable(subTable, c.Tags); err != nil { log.Printf("Could not parse [tags] config\n") return err } @@ -531,15 +398,15 @@ func (c *Config) addOutput(name string, table *ast.Table) error { return err } - if err := toml.UnmarshalTable(table, output); err != nil { + if err := config.UnmarshalTable(table, output); err != nil { return err } - ro := &RunningOutput{ - Name: name, - Output: output, - Config: outputConfig, + ro := models.NewRunningOutput(name, output, outputConfig) + if c.Agent.MetricBufferLimit > 0 { + ro.PointBufferLimit = c.Agent.MetricBufferLimit } + ro.Quiet = c.Agent.Quiet c.Outputs = append(c.Outputs, ro) return nil } @@ -564,11 +431,11 @@ func (c *Config) addInput(name string, table *ast.Table) error { return err } - if err := toml.UnmarshalTable(table, input); err != nil { + if err := config.UnmarshalTable(table, input); err != nil { return err } - rp := &RunningInput{ + rp := &models.RunningInput{ Name: name, Input: input, Config: pluginConfig, @@ -578,10 +445,10 @@ func (c *Config) addInput(name string, table *ast.Table) error { } // buildFilter builds a Filter (tagpass/tagdrop/pass/drop) to -// be inserted into the OutputConfig/InputConfig to be used for prefix +// be inserted into the models.OutputConfig/models.InputConfig to be used for prefix // filtering on tags and measurements -func buildFilter(tbl *ast.Table) Filter { - f := Filter{} +func buildFilter(tbl *ast.Table) models.Filter { + f := models.Filter{} if node, ok := tbl.Fields["pass"]; ok { if kv, ok := node.(*ast.KeyValue); ok { @@ -613,7 +480,7 @@ func buildFilter(tbl *ast.Table) Filter { if subtbl, ok := node.(*ast.Table); ok { for name, val := range subtbl.Fields { if kv, ok := val.(*ast.KeyValue); ok { - tagfilter := &TagFilter{Name: name} + tagfilter := &models.TagFilter{Name: name} if ary, ok := kv.Value.(*ast.Array); ok { for _, elem := range ary.Value { if str, ok := elem.(*ast.String); ok { @@ -632,7 +499,7 @@ func buildFilter(tbl *ast.Table) Filter { if subtbl, ok := node.(*ast.Table); ok { for name, val := range subtbl.Fields { if kv, ok := val.(*ast.KeyValue); ok { - tagfilter := &TagFilter{Name: name} + tagfilter := &models.TagFilter{Name: name} if ary, ok := kv.Value.(*ast.Array); ok { for _, elem := range ary.Value { if str, ok := elem.(*ast.String); ok { @@ -656,9 +523,9 @@ func buildFilter(tbl *ast.Table) Filter { // buildInput parses input specific items from the ast.Table, // builds the filter and returns a -// InputConfig to be inserted into RunningInput -func buildInput(name string, tbl *ast.Table) (*InputConfig, error) { - cp := &InputConfig{Name: name} +// models.InputConfig to be inserted into models.RunningInput +func buildInput(name string, tbl *ast.Table) (*models.InputConfig, error) { + cp := &models.InputConfig{Name: name} if node, ok := tbl.Fields["interval"]; ok { if kv, ok := node.(*ast.KeyValue); ok { if str, ok := kv.Value.(*ast.String); ok { @@ -699,7 +566,7 @@ func buildInput(name string, tbl *ast.Table) (*InputConfig, error) { cp.Tags = make(map[string]string) if node, ok := tbl.Fields["tags"]; ok { if subtbl, ok := node.(*ast.Table); ok { - if err := toml.UnmarshalTable(subtbl, cp.Tags); err != nil { + if err := config.UnmarshalTable(subtbl, cp.Tags); err != nil { log.Printf("Could not parse tags for input %s\n", name) } } @@ -715,10 +582,10 @@ func buildInput(name string, tbl *ast.Table) (*InputConfig, error) { } // buildOutput parses output specific items from the ast.Table, builds the filter and returns an -// OutputConfig to be inserted into RunningInput +// models.OutputConfig to be inserted into models.RunningInput // Note: error exists in the return for future calls that might require error -func buildOutput(name string, tbl *ast.Table) (*OutputConfig, error) { - oc := &OutputConfig{ +func buildOutput(name string, tbl *ast.Table) (*models.OutputConfig, error) { + oc := &models.OutputConfig{ Name: name, Filter: buildFilter(tbl), } diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 40af30c1e..92f45ad0a 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -4,6 +4,7 @@ import ( "testing" "time" + "github.com/influxdata/telegraf/internal/models" "github.com/influxdata/telegraf/plugins/inputs" "github.com/influxdata/telegraf/plugins/inputs/exec" "github.com/influxdata/telegraf/plugins/inputs/memcached" @@ -18,19 +19,19 @@ func TestConfig_LoadSingleInput(t *testing.T) { memcached := inputs.Inputs["memcached"]().(*memcached.Memcached) memcached.Servers = []string{"localhost"} - mConfig := &InputConfig{ + mConfig := &models.InputConfig{ Name: "memcached", - Filter: Filter{ + Filter: models.Filter{ Drop: []string{"other", "stuff"}, Pass: []string{"some", "strings"}, - TagDrop: []TagFilter{ - TagFilter{ + TagDrop: []models.TagFilter{ + models.TagFilter{ Name: "badtag", Filter: []string{"othertag"}, }, }, - TagPass: []TagFilter{ - TagFilter{ + TagPass: []models.TagFilter{ + models.TagFilter{ Name: "goodtag", Filter: []string{"mytag"}, }, @@ -61,19 +62,19 @@ func TestConfig_LoadDirectory(t *testing.T) { memcached := inputs.Inputs["memcached"]().(*memcached.Memcached) memcached.Servers = []string{"localhost"} - mConfig := &InputConfig{ + mConfig := &models.InputConfig{ Name: "memcached", - Filter: Filter{ + Filter: models.Filter{ Drop: []string{"other", "stuff"}, Pass: []string{"some", "strings"}, - TagDrop: []TagFilter{ - TagFilter{ + TagDrop: []models.TagFilter{ + models.TagFilter{ Name: "badtag", Filter: []string{"othertag"}, }, }, - TagPass: []TagFilter{ - TagFilter{ + TagPass: []models.TagFilter{ + models.TagFilter{ Name: "goodtag", Filter: []string{"mytag"}, }, @@ -91,7 +92,7 @@ func TestConfig_LoadDirectory(t *testing.T) { ex := inputs.Inputs["exec"]().(*exec.Exec) ex.Command = "/usr/bin/myothercollector --foo=bar" - eConfig := &InputConfig{ + eConfig := &models.InputConfig{ Name: "exec", MeasurementSuffix: "_myothercollector", } @@ -110,7 +111,7 @@ func TestConfig_LoadDirectory(t *testing.T) { pstat := inputs.Inputs["procstat"]().(*procstat.Procstat) pstat.PidFile = "/var/run/grafana-server.pid" - pConfig := &InputConfig{Name: "procstat"} + pConfig := &models.InputConfig{Name: "procstat"} pConfig.Tags = make(map[string]string) assert.Equal(t, pstat, c.Inputs[3].Input, @@ -118,175 +119,3 @@ func TestConfig_LoadDirectory(t *testing.T) { assert.Equal(t, pConfig, c.Inputs[3].Config, "Merged Testdata did not produce correct procstat metadata.") } - -func TestFilter_Empty(t *testing.T) { - f := Filter{} - - measurements := []string{ - "foo", - "bar", - "barfoo", - "foo_bar", - "foo.bar", - "foo-bar", - "supercalifradjulisticexpialidocious", - } - - for _, measurement := range measurements { - if !f.ShouldPass(measurement) { - t.Errorf("Expected measurement %s to pass", measurement) - } - } -} - -func TestFilter_Pass(t *testing.T) { - f := Filter{ - Pass: []string{"foo*", "cpu_usage_idle"}, - } - - passes := []string{ - "foo", - "foo_bar", - "foo.bar", - "foo-bar", - "cpu_usage_idle", - } - - drops := []string{ - "bar", - "barfoo", - "bar_foo", - "cpu_usage_busy", - } - - for _, measurement := range passes { - if !f.ShouldPass(measurement) { - t.Errorf("Expected measurement %s to pass", measurement) - } - } - - for _, measurement := range drops { - if f.ShouldPass(measurement) { - t.Errorf("Expected measurement %s to drop", measurement) - } - } -} - -func TestFilter_Drop(t *testing.T) { - f := Filter{ - Drop: []string{"foo*", "cpu_usage_idle"}, - } - - drops := []string{ - "foo", - "foo_bar", - "foo.bar", - "foo-bar", - "cpu_usage_idle", - } - - passes := []string{ - "bar", - "barfoo", - "bar_foo", - "cpu_usage_busy", - } - - for _, measurement := range passes { - if !f.ShouldPass(measurement) { - t.Errorf("Expected measurement %s to pass", measurement) - } - } - - for _, measurement := range drops { - if f.ShouldPass(measurement) { - t.Errorf("Expected measurement %s to drop", measurement) - } - } -} - -func TestFilter_TagPass(t *testing.T) { - filters := []TagFilter{ - TagFilter{ - Name: "cpu", - Filter: []string{"cpu-*"}, - }, - TagFilter{ - Name: "mem", - Filter: []string{"mem_free"}, - }} - f := Filter{ - TagPass: filters, - } - - passes := []map[string]string{ - {"cpu": "cpu-total"}, - {"cpu": "cpu-0"}, - {"cpu": "cpu-1"}, - {"cpu": "cpu-2"}, - {"mem": "mem_free"}, - } - - drops := []map[string]string{ - {"cpu": "cputotal"}, - {"cpu": "cpu0"}, - {"cpu": "cpu1"}, - {"cpu": "cpu2"}, - {"mem": "mem_used"}, - } - - for _, tags := range passes { - if !f.ShouldTagsPass(tags) { - t.Errorf("Expected tags %v to pass", tags) - } - } - - for _, tags := range drops { - if f.ShouldTagsPass(tags) { - t.Errorf("Expected tags %v to drop", tags) - } - } -} - -func TestFilter_TagDrop(t *testing.T) { - filters := []TagFilter{ - TagFilter{ - Name: "cpu", - Filter: []string{"cpu-*"}, - }, - TagFilter{ - Name: "mem", - Filter: []string{"mem_free"}, - }} - f := Filter{ - TagDrop: filters, - } - - drops := []map[string]string{ - {"cpu": "cpu-total"}, - {"cpu": "cpu-0"}, - {"cpu": "cpu-1"}, - {"cpu": "cpu-2"}, - {"mem": "mem_free"}, - } - - passes := []map[string]string{ - {"cpu": "cputotal"}, - {"cpu": "cpu0"}, - {"cpu": "cpu1"}, - {"cpu": "cpu2"}, - {"mem": "mem_used"}, - } - - for _, tags := range passes { - if !f.ShouldTagsPass(tags) { - t.Errorf("Expected tags %v to pass", tags) - } - } - - for _, tags := range drops { - if f.ShouldTagsPass(tags) { - t.Errorf("Expected tags %v to drop", tags) - } - } -} diff --git a/internal/models/filter.go b/internal/models/filter.go new file mode 100644 index 000000000..3f171ccac --- /dev/null +++ b/internal/models/filter.go @@ -0,0 +1,92 @@ +package models + +import ( + "strings" + + "github.com/influxdata/influxdb/client/v2" + "github.com/influxdata/telegraf/internal" +) + +// TagFilter is the name of a tag, and the values on which to filter +type TagFilter struct { + Name string + Filter []string +} + +// Filter containing drop/pass and tagdrop/tagpass rules +type Filter struct { + Drop []string + Pass []string + + TagDrop []TagFilter + TagPass []TagFilter + + IsActive bool +} + +func (f Filter) ShouldPointPass(point *client.Point) bool { + if f.ShouldPass(point.Name()) && f.ShouldTagsPass(point.Tags()) { + return true + } + return false +} + +// ShouldPass returns true if the metric should pass, false if should drop +// based on the drop/pass filter parameters +func (f Filter) ShouldPass(key string) bool { + if f.Pass != nil { + for _, pat := range f.Pass { + // TODO remove HasPrefix check, leaving it for now for legacy support. + // Cam, 2015-12-07 + if strings.HasPrefix(key, pat) || internal.Glob(pat, key) { + return true + } + } + return false + } + + if f.Drop != nil { + for _, pat := range f.Drop { + // TODO remove HasPrefix check, leaving it for now for legacy support. + // Cam, 2015-12-07 + if strings.HasPrefix(key, pat) || internal.Glob(pat, key) { + return false + } + } + + return true + } + return true +} + +// ShouldTagsPass returns true if the metric should pass, false if should drop +// based on the tagdrop/tagpass filter parameters +func (f Filter) ShouldTagsPass(tags map[string]string) bool { + if f.TagPass != nil { + for _, pat := range f.TagPass { + if tagval, ok := tags[pat.Name]; ok { + for _, filter := range pat.Filter { + if internal.Glob(filter, tagval) { + return true + } + } + } + } + return false + } + + if f.TagDrop != nil { + for _, pat := range f.TagDrop { + if tagval, ok := tags[pat.Name]; ok { + for _, filter := range pat.Filter { + if internal.Glob(filter, tagval) { + return false + } + } + } + } + return true + } + + return true +} diff --git a/internal/models/filter_test.go b/internal/models/filter_test.go new file mode 100644 index 000000000..9e962e420 --- /dev/null +++ b/internal/models/filter_test.go @@ -0,0 +1,177 @@ +package models + +import ( + "testing" +) + +func TestFilter_Empty(t *testing.T) { + f := Filter{} + + measurements := []string{ + "foo", + "bar", + "barfoo", + "foo_bar", + "foo.bar", + "foo-bar", + "supercalifradjulisticexpialidocious", + } + + for _, measurement := range measurements { + if !f.ShouldPass(measurement) { + t.Errorf("Expected measurement %s to pass", measurement) + } + } +} + +func TestFilter_Pass(t *testing.T) { + f := Filter{ + Pass: []string{"foo*", "cpu_usage_idle"}, + } + + passes := []string{ + "foo", + "foo_bar", + "foo.bar", + "foo-bar", + "cpu_usage_idle", + } + + drops := []string{ + "bar", + "barfoo", + "bar_foo", + "cpu_usage_busy", + } + + for _, measurement := range passes { + if !f.ShouldPass(measurement) { + t.Errorf("Expected measurement %s to pass", measurement) + } + } + + for _, measurement := range drops { + if f.ShouldPass(measurement) { + t.Errorf("Expected measurement %s to drop", measurement) + } + } +} + +func TestFilter_Drop(t *testing.T) { + f := Filter{ + Drop: []string{"foo*", "cpu_usage_idle"}, + } + + drops := []string{ + "foo", + "foo_bar", + "foo.bar", + "foo-bar", + "cpu_usage_idle", + } + + passes := []string{ + "bar", + "barfoo", + "bar_foo", + "cpu_usage_busy", + } + + for _, measurement := range passes { + if !f.ShouldPass(measurement) { + t.Errorf("Expected measurement %s to pass", measurement) + } + } + + for _, measurement := range drops { + if f.ShouldPass(measurement) { + t.Errorf("Expected measurement %s to drop", measurement) + } + } +} + +func TestFilter_TagPass(t *testing.T) { + filters := []TagFilter{ + TagFilter{ + Name: "cpu", + Filter: []string{"cpu-*"}, + }, + TagFilter{ + Name: "mem", + Filter: []string{"mem_free"}, + }} + f := Filter{ + TagPass: filters, + } + + passes := []map[string]string{ + {"cpu": "cpu-total"}, + {"cpu": "cpu-0"}, + {"cpu": "cpu-1"}, + {"cpu": "cpu-2"}, + {"mem": "mem_free"}, + } + + drops := []map[string]string{ + {"cpu": "cputotal"}, + {"cpu": "cpu0"}, + {"cpu": "cpu1"}, + {"cpu": "cpu2"}, + {"mem": "mem_used"}, + } + + for _, tags := range passes { + if !f.ShouldTagsPass(tags) { + t.Errorf("Expected tags %v to pass", tags) + } + } + + for _, tags := range drops { + if f.ShouldTagsPass(tags) { + t.Errorf("Expected tags %v to drop", tags) + } + } +} + +func TestFilter_TagDrop(t *testing.T) { + filters := []TagFilter{ + TagFilter{ + Name: "cpu", + Filter: []string{"cpu-*"}, + }, + TagFilter{ + Name: "mem", + Filter: []string{"mem_free"}, + }} + f := Filter{ + TagDrop: filters, + } + + drops := []map[string]string{ + {"cpu": "cpu-total"}, + {"cpu": "cpu-0"}, + {"cpu": "cpu-1"}, + {"cpu": "cpu-2"}, + {"mem": "mem_free"}, + } + + passes := []map[string]string{ + {"cpu": "cputotal"}, + {"cpu": "cpu0"}, + {"cpu": "cpu1"}, + {"cpu": "cpu2"}, + {"mem": "mem_used"}, + } + + for _, tags := range passes { + if !f.ShouldTagsPass(tags) { + t.Errorf("Expected tags %v to pass", tags) + } + } + + for _, tags := range drops { + if f.ShouldTagsPass(tags) { + t.Errorf("Expected tags %v to drop", tags) + } + } +} diff --git a/internal/models/running_input.go b/internal/models/running_input.go new file mode 100644 index 000000000..17c0d2129 --- /dev/null +++ b/internal/models/running_input.go @@ -0,0 +1,24 @@ +package models + +import ( + "time" + + "github.com/influxdata/telegraf/plugins/inputs" +) + +type RunningInput struct { + Name string + Input inputs.Input + Config *InputConfig +} + +// InputConfig containing a name, interval, and filter +type InputConfig struct { + Name string + NameOverride string + MeasurementPrefix string + MeasurementSuffix string + Tags map[string]string + Filter Filter + Interval time.Duration +} diff --git a/internal/models/running_output.go b/internal/models/running_output.go new file mode 100644 index 000000000..196ebdc8a --- /dev/null +++ b/internal/models/running_output.go @@ -0,0 +1,77 @@ +package models + +import ( + "log" + "time" + + "github.com/influxdata/telegraf/plugins/outputs" + + "github.com/influxdata/influxdb/client/v2" +) + +const DEFAULT_POINT_BUFFER_LIMIT = 10000 + +type RunningOutput struct { + Name string + Output outputs.Output + Config *OutputConfig + Quiet bool + PointBufferLimit int + + points []*client.Point + overwriteCounter int +} + +func NewRunningOutput( + name string, + output outputs.Output, + conf *OutputConfig, +) *RunningOutput { + ro := &RunningOutput{ + Name: name, + points: make([]*client.Point, 0), + Output: output, + Config: conf, + PointBufferLimit: DEFAULT_POINT_BUFFER_LIMIT, + } + return ro +} + +func (ro *RunningOutput) AddPoint(point *client.Point) { + if ro.Config.Filter.IsActive { + if !ro.Config.Filter.ShouldPointPass(point) { + return + } + } + + if len(ro.points) < ro.PointBufferLimit { + ro.points = append(ro.points, point) + } else { + if ro.overwriteCounter == len(ro.points) { + ro.overwriteCounter = 0 + } + ro.points[ro.overwriteCounter] = point + ro.overwriteCounter++ + } +} + +func (ro *RunningOutput) Write() error { + start := time.Now() + err := ro.Output.Write(ro.points) + elapsed := time.Since(start) + if err == nil { + if !ro.Quiet { + log.Printf("Wrote %d metrics to output %s in %s\n", + len(ro.points), ro.Name, elapsed) + } + ro.points = make([]*client.Point, 0) + ro.overwriteCounter = 0 + } + return err +} + +// OutputConfig containing name and filter +type OutputConfig struct { + Name string + Filter Filter +} diff --git a/plugins/inputs/EXAMPLE_README.md b/plugins/inputs/EXAMPLE_README.md new file mode 100644 index 000000000..16aaac8ef --- /dev/null +++ b/plugins/inputs/EXAMPLE_README.md @@ -0,0 +1,39 @@ +# Example Input Plugin + +The example plugin gathers metrics about example things + +### Configuration: + +``` +# Description +[[inputs.example]] + # SampleConfig +``` + +### Measurements & Fields: + + + +- measurement1 + - field1 (type, unit) + - field2 (float, percent) +- measurement2 + - field3 (integer, bytes) + +### Tags: + +- All measurements have the following tags: + - tag1 (optional description) + - tag2 +- measurement2 has the following tags: + - tag3 + +### Example Output: + +Give an example `-test` output here + +``` +$ ./telegraf -config telegraf.conf -input-filter example -test +measurement1,tag1=foo,tag2=bar field1=1i,field2=2.1 1453831884664956455 +measurement2,tag1=foo,tag2=bar,tag3=baz field3=1i 1453831884664956455 +``` diff --git a/plugins/inputs/all/all.go b/plugins/inputs/all/all.go index 570a027ed..32e109304 100644 --- a/plugins/inputs/all/all.go +++ b/plugins/inputs/all/all.go @@ -8,6 +8,7 @@ import ( _ "github.com/influxdata/telegraf/plugins/inputs/docker" _ "github.com/influxdata/telegraf/plugins/inputs/elasticsearch" _ "github.com/influxdata/telegraf/plugins/inputs/exec" + _ "github.com/influxdata/telegraf/plugins/inputs/github_webhooks" _ "github.com/influxdata/telegraf/plugins/inputs/haproxy" _ "github.com/influxdata/telegraf/plugins/inputs/httpjson" _ "github.com/influxdata/telegraf/plugins/inputs/influxdb" @@ -33,6 +34,8 @@ import ( _ "github.com/influxdata/telegraf/plugins/inputs/redis" _ "github.com/influxdata/telegraf/plugins/inputs/rethinkdb" _ "github.com/influxdata/telegraf/plugins/inputs/sensors" + _ "github.com/influxdata/telegraf/plugins/inputs/snmp" + _ "github.com/influxdata/telegraf/plugins/inputs/sqlserver" _ "github.com/influxdata/telegraf/plugins/inputs/statsd" _ "github.com/influxdata/telegraf/plugins/inputs/system" _ "github.com/influxdata/telegraf/plugins/inputs/trig" diff --git a/plugins/inputs/docker/docker.go b/plugins/inputs/docker/docker.go index 70fcaa19a..0e96dd176 100644 --- a/plugins/inputs/docker/docker.go +++ b/plugins/inputs/docker/docker.go @@ -110,15 +110,12 @@ func (d *Docker) gatherContainer( Timeout: time.Duration(time.Second * 5), } - var err error go func() { - err = d.client.Stats(statOpts) + d.client.Stats(statOpts) }() stat := <-statChan - if err != nil { - return err - } + close(done) // Add labels to tags for k, v := range container.Labels { diff --git a/plugins/inputs/exec/exec.go b/plugins/inputs/exec/exec.go index 603ba1464..0fc0b098a 100644 --- a/plugins/inputs/exec/exec.go +++ b/plugins/inputs/exec/exec.go @@ -13,6 +13,9 @@ import ( ) const sampleConfig = ` + # NOTE This plugin only reads numerical measurements, strings and booleans + # will be ignored. + # the command to run command = "/usr/bin/mycollector --foo=bar" diff --git a/plugins/inputs/github_webhooks/README.md b/plugins/inputs/github_webhooks/README.md new file mode 100644 index 000000000..230e5366b --- /dev/null +++ b/plugins/inputs/github_webhooks/README.md @@ -0,0 +1,369 @@ +# github_webhooks + +This is a Telegraf service plugin that listens for events kicked off by Github's Webhooks service and persists data from them into configured outputs. To set up the listener first generate the proper configuration: +```sh +$ telegraf -sample-config -input-filter github_webhooks -output-filter influxdb > config.conf.new +``` +Change the config file to point to the InfluxDB server you are using and adjust the settings to match your environment. Once that is complete: +```sh +$ cp config.conf.new /etc/telegraf/telegraf.conf +$ sudo service telegraf start +``` +Once the server is running you should configure your Organization's Webhooks to point at the `github_webhooks` service. To do this go to `github.com/{my_organization}` and click `Settings > Webhooks > Add webhook`. In the resulting menu set `Payload URL` to `http://:1618`, `Content type` to `application/json` and under the section `Which events would you like to trigger this webhook?` select 'Send me everything'. By default all of the events will write to the `github_webhooks` measurement, this is configurable by setting the `measurement_name` in the config file. + +## Events + +The titles of the following sections are links to the full payloads and details for each event. The body contains what information from the event is persisted. The format is as follows: +``` +# TAGS +* 'tagKey' = `tagValue` type +# FIELDS +* 'fieldKey' = `fieldValue` type +``` +The tag values and field values show the place on the incoming JSON object where the data is sourced from. + +#### [`commit_comment` event](https://developer.github.com/v3/activity/events/types/#commitcommentevent) + +**Tags:** +* 'event' = `headers[X-Github-Event]` string +* 'repository' = `event.repository.full_name` string +* 'private' = `event.repository.private` bool +* 'user' = `event.sender.login` string +* 'admin' = `event.sender.site_admin` bool + +**Fields:** +* 'stars' = `event.repository.stargazers_count` int +* 'forks' = `event.repository.forks_count` int +* 'issues' = `event.repository.open_issues_count` int +* 'commit' = `event.comment.commit_id` string +* 'comment' = `event.comment.body` string + +#### [`create` event](https://developer.github.com/v3/activity/events/types/#createevent) + +**Tags:** +* 'event' = `headers[X-Github-Event]` string +* 'repository' = `event.repository.full_name` string +* 'private' = `event.repository.private` bool +* 'user' = `event.sender.login` string +* 'admin' = `event.sender.site_admin` bool + +**Fields:** +* 'stars' = `event.repository.stargazers_count` int +* 'forks' = `event.repository.forks_count` int +* 'issues' = `event.repository.open_issues_count` int +* 'ref' = `event.ref` string +* 'issues' = `event.ref_type` string + +#### [`delete` event](https://developer.github.com/v3/activity/events/types/#deleteevent) + +**Tags:** +* 'event' = `headers[X-Github-Event]` string +* 'repository' = `event.repository.full_name` string +* 'private' = `event.repository.private` bool +* 'user' = `event.sender.login` string +* 'admin' = `event.sender.site_admin` bool + +**Fields:** +* 'stars' = `event.repository.stargazers_count` int +* 'forks' = `event.repository.forks_count` int +* 'issues' = `event.repository.open_issues_count` int +* 'ref' = `event.ref` string +* 'issues' = `event.ref_type` string + +#### [`deployment` event](https://developer.github.com/v3/activity/events/types/#deploymentevent) + +**Tags:** +* 'event' = `headers[X-Github-Event]` string +* 'repository' = `event.repository.full_name` string +* 'private' = `event.repository.private` bool +* 'user' = `event.sender.login` string +* 'admin' = `event.sender.site_admin` bool + +**Fields:** +* 'stars' = `event.repository.stargazers_count` int +* 'forks' = `event.repository.forks_count` int +* 'issues' = `event.repository.open_issues_count` int +* 'commit' = `event.deployment.sha` string +* 'task' = `event.deployment.task` string +* 'environment' = `event.deployment.evnironment` string +* 'description' = `event.deployment.description` string + +#### [`deployment_status` event](https://developer.github.com/v3/activity/events/types/#deploymentstatusevent) + +**Tags:** +* 'event' = `headers[X-Github-Event]` string +* 'repository' = `event.repository.full_name` string +* 'private' = `event.repository.private` bool +* 'user' = `event.sender.login` string +* 'admin' = `event.sender.site_admin` bool + +**Fields:** +* 'stars' = `event.repository.stargazers_count` int +* 'forks' = `event.repository.forks_count` int +* 'issues' = `event.repository.open_issues_count` int +* 'commit' = `event.deployment.sha` string +* 'task' = `event.deployment.task` string +* 'environment' = `event.deployment.evnironment` string +* 'description' = `event.deployment.description` string +* 'depState' = `event.deployment_status.state` string +* 'depDescription' = `event.deployment_status.description` string + +#### [`fork` event](https://developer.github.com/v3/activity/events/types/#forkevent) + +**Tags:** +* 'event' = `headers[X-Github-Event]` string +* 'repository' = `event.repository.full_name` string +* 'private' = `event.repository.private` bool +* 'user' = `event.sender.login` string +* 'admin' = `event.sender.site_admin` bool + +**Fields:** +* 'stars' = `event.repository.stargazers_count` int +* 'forks' = `event.repository.forks_count` int +* 'issues' = `event.repository.open_issues_count` int +* 'forkee' = `event.forkee.repository` string + +#### [`gollum` event](https://developer.github.com/v3/activity/events/types/#gollumevent) + +**Tags:** +* 'event' = `headers[X-Github-Event]` string +* 'repository' = `event.repository.full_name` string +* 'private' = `event.repository.private` bool +* 'user' = `event.sender.login` string +* 'admin' = `event.sender.site_admin` bool + +**Fields:** +* 'stars' = `event.repository.stargazers_count` int +* 'forks' = `event.repository.forks_count` int +* 'issues' = `event.repository.open_issues_count` int + +#### [`issue_comment` event](https://developer.github.com/v3/activity/events/types/#issuecommentevent) + +**Tags:** +* 'event' = `headers[X-Github-Event]` string +* 'repository' = `event.repository.full_name` string +* 'private' = `event.repository.private` bool +* 'user' = `event.sender.login` string +* 'admin' = `event.sender.site_admin` bool +* 'issue' = `event.issue.number` int + +**Fields:** +* 'stars' = `event.repository.stargazers_count` int +* 'forks' = `event.repository.forks_count` int +* 'issues' = `event.repository.open_issues_count` int +* 'title' = `event.issue.title` string +* 'comments' = `event.issue.comments` int +* 'body' = `event.comment.body` string + +#### [`issues` event](https://developer.github.com/v3/activity/events/types/#issuesevent) + +**Tags:** +* 'event' = `headers[X-Github-Event]` string +* 'repository' = `event.repository.full_name` string +* 'private' = `event.repository.private` bool +* 'user' = `event.sender.login` string +* 'admin' = `event.sender.site_admin` bool +* 'issue' = `event.issue.number` int +* 'action' = `event.action` string + +**Fields:** +* 'stars' = `event.repository.stargazers_count` int +* 'forks' = `event.repository.forks_count` int +* 'issues' = `event.repository.open_issues_count` int +* 'title' = `event.issue.title` string +* 'comments' = `event.issue.comments` int + +#### [`member` event](https://developer.github.com/v3/activity/events/types/#memberevent) + +**Tags:** +* 'event' = `headers[X-Github-Event]` string +* 'repository' = `event.repository.full_name` string +* 'private' = `event.repository.private` bool +* 'user' = `event.sender.login` string +* 'admin' = `event.sender.site_admin` bool + +**Fields:** +* 'stars' = `event.repository.stargazers_count` int +* 'forks' = `event.repository.forks_count` int +* 'issues' = `event.repository.open_issues_count` int +* 'newMember' = `event.sender.login` string +* 'newMemberStatus' = `event.sender.site_admin` bool + +#### [`membership` event](https://developer.github.com/v3/activity/events/types/#membershipevent) + +**Tags:** +* 'event' = `headers[X-Github-Event]` string +* 'user' = `event.sender.login` string +* 'admin' = `event.sender.site_admin` bool +* 'action' = `event.action` string + +**Fields:** +* 'newMember' = `event.sender.login` string +* 'newMemberStatus' = `event.sender.site_admin` bool + +#### [`page_build` event](https://developer.github.com/v3/activity/events/types/#pagebuildevent) + +**Tags:** +* 'event' = `headers[X-Github-Event]` string +* 'repository' = `event.repository.full_name` string +* 'private' = `event.repository.private` bool +* 'user' = `event.sender.login` string +* 'admin' = `event.sender.site_admin` bool + +**Fields:** +* 'stars' = `event.repository.stargazers_count` int +* 'forks' = `event.repository.forks_count` int +* 'issues' = `event.repository.open_issues_count` int + +#### [`public` event](https://developer.github.com/v3/activity/events/types/#publicevent) + +**Tags:** +* 'event' = `headers[X-Github-Event]` string +* 'repository' = `event.repository.full_name` string +* 'private' = `event.repository.private` bool +* 'user' = `event.sender.login` string +* 'admin' = `event.sender.site_admin` bool + +**Fields:** +* 'stars' = `event.repository.stargazers_count` int +* 'forks' = `event.repository.forks_count` int +* 'issues' = `event.repository.open_issues_count` int + +#### [`pull_request_review_comment` event](https://developer.github.com/v3/activity/events/types/#pullrequestreviewcommentevent) + +**Tags:** +* 'event' = `headers[X-Github-Event]` string +* 'action' = `event.action` string +* 'repository' = `event.repository.full_name` string +* 'private' = `event.repository.private` bool +* 'user' = `event.sender.login` string +* 'admin' = `event.sender.site_admin` bool +* 'prNumber' = `event.pull_request.number` int + +**Fields:** +* 'stars' = `event.repository.stargazers_count` int +* 'forks' = `event.repository.forks_count` int +* 'issues' = `event.repository.open_issues_count` int +* 'state' = `event.pull_request.state` string +* 'title' = `event.pull_request.title` string +* 'comments' = `event.pull_request.comments` int +* 'commits' = `event.pull_request.commits` int +* 'additions' = `event.pull_request.additions` int +* 'deletions' = `event.pull_request.deletions` int +* 'changedFiles' = `event.pull_request.changed_files` int +* 'commentFile' = `event.comment.file` string +* 'comment' = `event.comment.body` string + +#### [`pull_request` event](https://developer.github.com/v3/activity/events/types/#pullrequestevent) + +**Tags:** +* 'event' = `headers[X-Github-Event]` string +* 'action' = `event.action` string +* 'repository' = `event.repository.full_name` string +* 'private' = `event.repository.private` bool +* 'user' = `event.sender.login` string +* 'admin' = `event.sender.site_admin` bool +* 'prNumber' = `event.pull_request.number` int + +**Fields:** +* 'stars' = `event.repository.stargazers_count` int +* 'forks' = `event.repository.forks_count` int +* 'issues' = `event.repository.open_issues_count` int +* 'state' = `event.pull_request.state` string +* 'title' = `event.pull_request.title` string +* 'comments' = `event.pull_request.comments` int +* 'commits' = `event.pull_request.commits` int +* 'additions' = `event.pull_request.additions` int +* 'deletions' = `event.pull_request.deletions` int +* 'changedFiles' = `event.pull_request.changed_files` int + +#### [`push` event](https://developer.github.com/v3/activity/events/types/#pushevent) + +**Tags:** +* 'event' = `headers[X-Github-Event]` string +* 'repository' = `event.repository.full_name` string +* 'private' = `event.repository.private` bool +* 'user' = `event.sender.login` string +* 'admin' = `event.sender.site_admin` bool + +**Fields:** +* 'stars' = `event.repository.stargazers_count` int +* 'forks' = `event.repository.forks_count` int +* 'issues' = `event.repository.open_issues_count` int +* 'ref' = `event.ref` string +* 'before' = `event.before` string +* 'after' = `event.after` string + +#### [`repository` event](https://developer.github.com/v3/activity/events/types/#repositoryevent) + +**Tags:** +* 'event' = `headers[X-Github-Event]` string +* 'repository' = `event.repository.full_name` string +* 'private' = `event.repository.private` bool +* 'user' = `event.sender.login` string +* 'admin' = `event.sender.site_admin` bool + +**Fields:** +* 'stars' = `event.repository.stargazers_count` int +* 'forks' = `event.repository.forks_count` int +* 'issues' = `event.repository.open_issues_count` int + +#### [`release` event](https://developer.github.com/v3/activity/events/types/#releaseevent) + +**Tags:** +* 'event' = `headers[X-Github-Event]` string +* 'repository' = `event.repository.full_name` string +* 'private' = `event.repository.private` bool +* 'user' = `event.sender.login` string +* 'admin' = `event.sender.site_admin` bool + +**Fields:** +* 'stars' = `event.repository.stargazers_count` int +* 'forks' = `event.repository.forks_count` int +* 'issues' = `event.repository.open_issues_count` int +* 'tagName' = `event.release.tag_name` string + +#### [`status` event](https://developer.github.com/v3/activity/events/types/#statusevent) + +**Tags:** +* 'event' = `headers[X-Github-Event]` string +* 'repository' = `event.repository.full_name` string +* 'private' = `event.repository.private` bool +* 'user' = `event.sender.login` string +* 'admin' = `event.sender.site_admin` bool + +**Fields:** +* 'stars' = `event.repository.stargazers_count` int +* 'forks' = `event.repository.forks_count` int +* 'issues' = `event.repository.open_issues_count` int +* 'commit' = `event.sha` string +* 'state' = `event.state` string + +#### [`team_add` event](https://developer.github.com/v3/activity/events/types/#teamaddevent) + +**Tags:** +* 'event' = `headers[X-Github-Event]` string +* 'repository' = `event.repository.full_name` string +* 'private' = `event.repository.private` bool +* 'user' = `event.sender.login` string +* 'admin' = `event.sender.site_admin` bool + +**Fields:** +* 'stars' = `event.repository.stargazers_count` int +* 'forks' = `event.repository.forks_count` int +* 'issues' = `event.repository.open_issues_count` int +* 'teamName' = `event.team.name` string + +#### [`watch` event](https://developer.github.com/v3/activity/events/types/#watchevent) + +**Tags:** +* 'event' = `headers[X-Github-Event]` string +* 'repository' = `event.repository.full_name` string +* 'private' = `event.repository.private` bool +* 'user' = `event.sender.login` string +* 'admin' = `event.sender.site_admin` bool + +**Fields:** +* 'stars' = `event.repository.stargazers_count` int +* 'forks' = `event.repository.forks_count` int +* 'issues' = `event.repository.open_issues_count` int diff --git a/plugins/inputs/github_webhooks/github_webhooks.go b/plugins/inputs/github_webhooks/github_webhooks.go new file mode 100644 index 000000000..f764a5136 --- /dev/null +++ b/plugins/inputs/github_webhooks/github_webhooks.go @@ -0,0 +1,334 @@ +package github_webhooks + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "log" + "net/http" + "sync" + + "github.com/gorilla/mux" + "github.com/influxdata/telegraf/plugins/inputs" +) + +func init() { + inputs.Add("github_webhooks", func() inputs.Input { return &GithubWebhooks{} }) +} + +type GithubWebhooks struct { + ServiceAddress string + // Lock for the struct + sync.Mutex + // Events buffer to store events between Gather calls + events []Event +} + +func NewGithubWebhooks() *GithubWebhooks { + return &GithubWebhooks{} +} + +func (gh *GithubWebhooks) SampleConfig() string { + return ` + # Address and port to host Webhook listener on + service_address = ":1618" +` +} + +func (gh *GithubWebhooks) Description() string { + return "A Github Webhook Event collector" +} + +// Writes the points from <-gh.in to the Accumulator +func (gh *GithubWebhooks) Gather(acc inputs.Accumulator) error { + gh.Lock() + defer gh.Unlock() + for _, event := range gh.events { + p := event.NewPoint() + acc.AddFields("github_webhooks", p.Fields(), p.Tags(), p.Time()) + } + gh.events = make([]Event, 0) + return nil +} + +func (gh *GithubWebhooks) Listen() { + r := mux.NewRouter() + r.HandleFunc("/", gh.eventHandler).Methods("POST") + err := http.ListenAndServe(fmt.Sprintf("%s", gh.ServiceAddress), r) + if err != nil { + log.Printf("Error starting server: %v", err) + } +} + +func (gh *GithubWebhooks) Start() error { + go gh.Listen() + log.Printf("Started the github_webhooks service on %s\n", gh.ServiceAddress) + return nil +} + +func (gh *GithubWebhooks) Stop() { + log.Println("Stopping the ghWebhooks service") +} + +// Handles the / route +func (gh *GithubWebhooks) eventHandler(w http.ResponseWriter, r *http.Request) { + eventType := r.Header["X-Github-Event"][0] + data, err := ioutil.ReadAll(r.Body) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + } + e, err := NewEvent(data, eventType) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + } + gh.Lock() + gh.events = append(gh.events, e) + gh.Unlock() + w.WriteHeader(http.StatusOK) +} + +func newCommitComment(data []byte) (Event, error) { + commitCommentStruct := CommitCommentEvent{} + err := json.Unmarshal(data, &commitCommentStruct) + if err != nil { + return nil, err + } + return commitCommentStruct, nil +} + +func newCreate(data []byte) (Event, error) { + createStruct := CreateEvent{} + err := json.Unmarshal(data, &createStruct) + if err != nil { + return nil, err + } + return createStruct, nil +} + +func newDelete(data []byte) (Event, error) { + deleteStruct := DeleteEvent{} + err := json.Unmarshal(data, &deleteStruct) + if err != nil { + return nil, err + } + return deleteStruct, nil +} + +func newDeployment(data []byte) (Event, error) { + deploymentStruct := DeploymentEvent{} + err := json.Unmarshal(data, &deploymentStruct) + if err != nil { + return nil, err + } + return deploymentStruct, nil +} + +func newDeploymentStatus(data []byte) (Event, error) { + deploymentStatusStruct := DeploymentStatusEvent{} + err := json.Unmarshal(data, &deploymentStatusStruct) + if err != nil { + return nil, err + } + return deploymentStatusStruct, nil +} + +func newFork(data []byte) (Event, error) { + forkStruct := ForkEvent{} + err := json.Unmarshal(data, &forkStruct) + if err != nil { + return nil, err + } + return forkStruct, nil +} + +func newGollum(data []byte) (Event, error) { + gollumStruct := GollumEvent{} + err := json.Unmarshal(data, &gollumStruct) + if err != nil { + return nil, err + } + return gollumStruct, nil +} + +func newIssueComment(data []byte) (Event, error) { + issueCommentStruct := IssueCommentEvent{} + err := json.Unmarshal(data, &issueCommentStruct) + if err != nil { + return nil, err + } + return issueCommentStruct, nil +} + +func newIssues(data []byte) (Event, error) { + issuesStruct := IssuesEvent{} + err := json.Unmarshal(data, &issuesStruct) + if err != nil { + return nil, err + } + return issuesStruct, nil +} + +func newMember(data []byte) (Event, error) { + memberStruct := MemberEvent{} + err := json.Unmarshal(data, &memberStruct) + if err != nil { + return nil, err + } + return memberStruct, nil +} + +func newMembership(data []byte) (Event, error) { + membershipStruct := MembershipEvent{} + err := json.Unmarshal(data, &membershipStruct) + if err != nil { + return nil, err + } + return membershipStruct, nil +} + +func newPageBuild(data []byte) (Event, error) { + pageBuildEvent := PageBuildEvent{} + err := json.Unmarshal(data, &pageBuildEvent) + if err != nil { + return nil, err + } + return pageBuildEvent, nil +} + +func newPublic(data []byte) (Event, error) { + publicEvent := PublicEvent{} + err := json.Unmarshal(data, &publicEvent) + if err != nil { + return nil, err + } + return publicEvent, nil +} + +func newPullRequest(data []byte) (Event, error) { + pullRequestStruct := PullRequestEvent{} + err := json.Unmarshal(data, &pullRequestStruct) + if err != nil { + return nil, err + } + return pullRequestStruct, nil +} + +func newPullRequestReviewComment(data []byte) (Event, error) { + pullRequestReviewCommentStruct := PullRequestReviewCommentEvent{} + err := json.Unmarshal(data, &pullRequestReviewCommentStruct) + if err != nil { + return nil, err + } + return pullRequestReviewCommentStruct, nil +} + +func newPush(data []byte) (Event, error) { + pushStruct := PushEvent{} + err := json.Unmarshal(data, &pushStruct) + if err != nil { + return nil, err + } + return pushStruct, nil +} + +func newRelease(data []byte) (Event, error) { + releaseStruct := ReleaseEvent{} + err := json.Unmarshal(data, &releaseStruct) + if err != nil { + return nil, err + } + return releaseStruct, nil +} + +func newRepository(data []byte) (Event, error) { + repositoryStruct := RepositoryEvent{} + err := json.Unmarshal(data, &repositoryStruct) + if err != nil { + return nil, err + } + return repositoryStruct, nil +} + +func newStatus(data []byte) (Event, error) { + statusStruct := StatusEvent{} + err := json.Unmarshal(data, &statusStruct) + if err != nil { + return nil, err + } + return statusStruct, nil +} + +func newTeamAdd(data []byte) (Event, error) { + teamAddStruct := TeamAddEvent{} + err := json.Unmarshal(data, &teamAddStruct) + if err != nil { + return nil, err + } + return teamAddStruct, nil +} + +func newWatch(data []byte) (Event, error) { + watchStruct := WatchEvent{} + err := json.Unmarshal(data, &watchStruct) + if err != nil { + return nil, err + } + return watchStruct, nil +} + +type newEventError struct { + s string +} + +func (e *newEventError) Error() string { + return e.s +} + +func NewEvent(r []byte, t string) (Event, error) { + log.Printf("New %v event recieved", t) + switch t { + case "commit_comment": + return newCommitComment(r) + case "create": + return newCreate(r) + case "delete": + return newDelete(r) + case "deployment": + return newDeployment(r) + case "deployment_status": + return newDeploymentStatus(r) + case "fork": + return newFork(r) + case "gollum": + return newGollum(r) + case "issue_comment": + return newIssueComment(r) + case "issues": + return newIssues(r) + case "member": + return newMember(r) + case "membership": + return newMembership(r) + case "page_build": + return newPageBuild(r) + case "public": + return newPublic(r) + case "pull_request": + return newPullRequest(r) + case "pull_request_review_comment": + return newPullRequestReviewComment(r) + case "push": + return newPush(r) + case "release": + return newRelease(r) + case "repository": + return newRepository(r) + case "status": + return newStatus(r) + case "team_add": + return newTeamAdd(r) + case "watch": + return newWatch(r) + } + return nil, &newEventError{"Not a recgonized event type"} +} diff --git a/plugins/inputs/github_webhooks/github_webhooks_mock_json.go b/plugins/inputs/github_webhooks/github_webhooks_mock_json.go new file mode 100644 index 000000000..386d62e65 --- /dev/null +++ b/plugins/inputs/github_webhooks/github_webhooks_mock_json.go @@ -0,0 +1,3559 @@ +package github_webhooks + +func CommitCommentEventJSON() string { + return `{ + "action": "created", + "comment": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/comments/11056394", + "html_url": "https://github.com/baxterthehacker/public-repo/commit/9049f1265b7d61be4a8904a9a27120d2064dab3b#commitcomment-11056394", + "id": 11056394, + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "position": null, + "line": null, + "path": null, + "commit_id": "9049f1265b7d61be4a8904a9a27120d2064dab3b", + "created_at": "2015-05-05T23:40:29Z", + "updated_at": "2015-05-05T23:40:29Z", + "body": "This is a really good change! :+1:" + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:27Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +}` +} + +func CreateEventJSON() string { + return `{ + "ref": "0.0.1", + "ref_type": "tag", + "master_branch": "master", + "description": "", + "pusher_type": "user", + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:38Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +}` +} + +func DeleteEventJSON() string { + return `{ + "ref": "simple-tag", + "ref_type": "tag", + "pusher_type": "user", + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:40Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +}` +} + +func DeploymentEventJSON() string { + return `{ + "deployment": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/deployments/710692", + "id": 710692, + "sha": "9049f1265b7d61be4a8904a9a27120d2064dab3b", + "ref": "master", + "task": "deploy", + "payload": { + }, + "environment": "production", + "description": null, + "creator": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "created_at": "2015-05-05T23:40:38Z", + "updated_at": "2015-05-05T23:40:38Z", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/deployments/710692/statuses", + "repository_url": "https://api.github.com/repos/baxterthehacker/public-repo" + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:38Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +}` +} + +func DeploymentStatusEventJSON() string { + return `{ + "deployment": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/deployments/710692", + "id": 710692, + "sha": "9049f1265b7d61be4a8904a9a27120d2064dab3b", + "ref": "master", + "task": "deploy", + "payload": { + }, + "environment": "production", + "description": null, + "creator": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "created_at": "2015-05-05T23:40:38Z", + "updated_at": "2015-05-05T23:40:38Z", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/deployments/710692/statuses", + "repository_url": "https://api.github.com/repos/baxterthehacker/public-repo" + }, + "deployment_status": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/deployments/710692/statuses/1115122", + "id": 1115122, + "state": "success", + "creator": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "description": null, + "target_url": null, + "created_at": "2015-05-05T23:40:39Z", + "updated_at": "2015-05-05T23:40:39Z", + "deployment_url": "https://api.github.com/repos/baxterthehacker/public-repo/deployments/710692", + "repository_url": "https://api.github.com/repos/baxterthehacker/public-repo" + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:38Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +} +` +} + +func ForkEventJSON() string { + return `{ + "forkee": { + "id": 35129393, + "name": "public-repo", + "full_name": "baxterandthehackers/public-repo", + "owner": { + "login": "baxterandthehackers", + "id": 7649605, + "avatar_url": "https://avatars.githubusercontent.com/u/7649605?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterandthehackers", + "html_url": "https://github.com/baxterandthehackers", + "followers_url": "https://api.github.com/users/baxterandthehackers/followers", + "following_url": "https://api.github.com/users/baxterandthehackers/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterandthehackers/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterandthehackers/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterandthehackers/subscriptions", + "organizations_url": "https://api.github.com/users/baxterandthehackers/orgs", + "repos_url": "https://api.github.com/users/baxterandthehackers/repos", + "events_url": "https://api.github.com/users/baxterandthehackers/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterandthehackers/received_events", + "type": "Organization", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterandthehackers/public-repo", + "description": "", + "fork": true, + "url": "https://api.github.com/repos/baxterandthehackers/public-repo", + "forks_url": "https://api.github.com/repos/baxterandthehackers/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterandthehackers/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterandthehackers/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterandthehackers/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterandthehackers/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterandthehackers/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterandthehackers/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterandthehackers/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterandthehackers/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterandthehackers/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterandthehackers/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterandthehackers/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterandthehackers/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterandthehackers/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterandthehackers/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterandthehackers/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterandthehackers/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterandthehackers/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterandthehackers/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterandthehackers/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterandthehackers/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterandthehackers/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterandthehackers/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterandthehackers/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterandthehackers/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterandthehackers/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterandthehackers/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterandthehackers/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterandthehackers/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterandthehackers/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:30Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:27Z", + "git_url": "git://github.com/baxterandthehackers/public-repo.git", + "ssh_url": "git@github.com:baxterandthehackers/public-repo.git", + "clone_url": "https://github.com/baxterandthehackers/public-repo.git", + "svn_url": "https://github.com/baxterandthehackers/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": false, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 0, + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "master", + "public": true + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:27Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 1, + "mirror_url": null, + "open_issues_count": 2, + "forks": 1, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterandthehackers", + "id": 7649605, + "avatar_url": "https://avatars.githubusercontent.com/u/7649605?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterandthehackers", + "html_url": "https://github.com/baxterandthehackers", + "followers_url": "https://api.github.com/users/baxterandthehackers/followers", + "following_url": "https://api.github.com/users/baxterandthehackers/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterandthehackers/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterandthehackers/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterandthehackers/subscriptions", + "organizations_url": "https://api.github.com/users/baxterandthehackers/orgs", + "repos_url": "https://api.github.com/users/baxterandthehackers/repos", + "events_url": "https://api.github.com/users/baxterandthehackers/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterandthehackers/received_events", + "type": "Organization", + "site_admin": false + } +}` +} + +func GollumEventJSON() string { + return `{ + "pages": [ + { + "page_name": "Home", + "title": "Home", + "summary": null, + "action": "created", + "sha": "91ea1bd42aa2ba166b86e8aefe049e9837214e67", + "html_url": "https://github.com/baxterthehacker/public-repo/wiki/Home" + } + ], + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:17Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 0, + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "jasonrudolph", + "id": 2988, + "avatar_url": "https://avatars.githubusercontent.com/u/2988?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/jasonrudolph", + "html_url": "https://github.com/jasonrudolph", + "followers_url": "https://api.github.com/users/jasonrudolph/followers", + "following_url": "https://api.github.com/users/jasonrudolph/following{/other_user}", + "gists_url": "https://api.github.com/users/jasonrudolph/gists{/gist_id}", + "starred_url": "https://api.github.com/users/jasonrudolph/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/jasonrudolph/subscriptions", + "organizations_url": "https://api.github.com/users/jasonrudolph/orgs", + "repos_url": "https://api.github.com/users/jasonrudolph/repos", + "events_url": "https://api.github.com/users/jasonrudolph/events{/privacy}", + "received_events_url": "https://api.github.com/users/jasonrudolph/received_events", + "type": "User", + "site_admin": true + } +}` +} + +func IssueCommentEventJSON() string { + return `{ + "action": "created", + "issue": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2/labels{/name}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2/comments", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2/events", + "html_url": "https://github.com/baxterthehacker/public-repo/issues/2", + "id": 73464126, + "number": 2, + "title": "Spelling error in the README file", + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "labels": [ + { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/labels/bug", + "name": "bug", + "color": "fc2929" + } + ], + "state": "open", + "locked": false, + "assignee": null, + "milestone": null, + "comments": 1, + "created_at": "2015-05-05T23:40:28Z", + "updated_at": "2015-05-05T23:40:28Z", + "closed_at": null, + "body": "It looks like you accidently spelled 'commit' with two 't's." + }, + "comment": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments/99262140", + "html_url": "https://github.com/baxterthehacker/public-repo/issues/2#issuecomment-99262140", + "issue_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2", + "id": 99262140, + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "created_at": "2015-05-05T23:40:28Z", + "updated_at": "2015-05-05T23:40:28Z", + "body": "You are totally right! I'll get this fixed right away." + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:27Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +}` +} + +func IssuesEventJSON() string { + return `{ + "action": "opened", + "issue": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2/labels{/name}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2/comments", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2/events", + "html_url": "https://github.com/baxterthehacker/public-repo/issues/2", + "id": 73464126, + "number": 2, + "title": "Spelling error in the README file", + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "labels": [ + { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/labels/bug", + "name": "bug", + "color": "fc2929" + } + ], + "state": "open", + "locked": false, + "assignee": null, + "milestone": null, + "comments": 0, + "created_at": "2015-05-05T23:40:28Z", + "updated_at": "2015-05-05T23:40:28Z", + "closed_at": null, + "body": "It looks like you accidently spelled 'commit' with two 't's." + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:27Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +}` +} + +func MemberEventJSON() string { + return `{ + "action": "added", + "member": { + "login": "octocat", + "id": 583231, + "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/octocat", + "html_url": "https://github.com/octocat", + "followers_url": "https://api.github.com/users/octocat/followers", + "following_url": "https://api.github.com/users/octocat/following{/other_user}", + "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", + "organizations_url": "https://api.github.com/users/octocat/orgs", + "repos_url": "https://api.github.com/users/octocat/repos", + "events_url": "https://api.github.com/users/octocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/octocat/received_events", + "type": "User", + "site_admin": false + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:40Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +}` +} + +func MembershipEventJSON() string { + return `{ + "action": "added", + "scope": "team", + "member": { + "login": "kdaigle", + "id": 2501, + "avatar_url": "https://avatars.githubusercontent.com/u/2501?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/kdaigle", + "html_url": "https://github.com/kdaigle", + "followers_url": "https://api.github.com/users/kdaigle/followers", + "following_url": "https://api.github.com/users/kdaigle/following{/other_user}", + "gists_url": "https://api.github.com/users/kdaigle/gists{/gist_id}", + "starred_url": "https://api.github.com/users/kdaigle/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/kdaigle/subscriptions", + "organizations_url": "https://api.github.com/users/kdaigle/orgs", + "repos_url": "https://api.github.com/users/kdaigle/repos", + "events_url": "https://api.github.com/users/kdaigle/events{/privacy}", + "received_events_url": "https://api.github.com/users/kdaigle/received_events", + "type": "User", + "site_admin": true + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=2", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "team": { + "name": "Contractors", + "id": 123456, + "slug": "contractors", + "permission": "admin", + "url": "https://api.github.com/teams/123456", + "members_url": "https://api.github.com/teams/123456/members{/member}", + "repositories_url": "https://api.github.com/teams/123456/repos" + }, + "organization": { + "login": "baxterandthehackers", + "id": 7649605, + "url": "https://api.github.com/orgs/baxterandthehackers", + "repos_url": "https://api.github.com/orgs/baxterandthehackers/repos", + "events_url": "https://api.github.com/orgs/baxterandthehackers/events", + "members_url": "https://api.github.com/orgs/baxterandthehackers/members{/member}", + "public_members_url": "https://api.github.com/orgs/baxterandthehackers/public_members{/member}", + "avatar_url": "https://avatars.githubusercontent.com/u/7649605?v=2" + } +}` +} + +func PageBuildEventJSON() string { + return `{ + "id": 15995382, + "build": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/pages/builds/15995382", + "status": "built", + "error": { + "message": null + }, + "pusher": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "commit": "053b99542c83021d6b202d1a1f5ecd5ef7084e55", + "duration": 3790, + "created_at": "2015-05-05T23:40:13Z", + "updated_at": "2015-05-05T23:40:17Z" + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:17Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 0, + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +}` +} + +func PublicEventJSON() string { + return `{ + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:41Z", + "pushed_at": "2015-05-05T23:40:40Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +}` +} + +func PullRequestReviewCommentEventJSON() string { + return `{ + "action": "created", + "comment": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/comments/29724692", + "id": 29724692, + "diff_hunk": "@@ -1 +1 @@\n-# public-repo", + "path": "README.md", + "position": 1, + "original_position": 1, + "commit_id": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "original_commit_id": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "body": "Maybe you should use more emojji on this line.", + "created_at": "2015-05-05T23:40:27Z", + "updated_at": "2015-05-05T23:40:27Z", + "html_url": "https://github.com/baxterthehacker/public-repo/pull/1#discussion_r29724692", + "pull_request_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1", + "_links": { + "self": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/comments/29724692" + }, + "html": { + "href": "https://github.com/baxterthehacker/public-repo/pull/1#discussion_r29724692" + }, + "pull_request": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1" + } + } + }, + "pull_request": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1", + "id": 34778301, + "html_url": "https://github.com/baxterthehacker/public-repo/pull/1", + "diff_url": "https://github.com/baxterthehacker/public-repo/pull/1.diff", + "patch_url": "https://github.com/baxterthehacker/public-repo/pull/1.patch", + "issue_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/1", + "number": 1, + "state": "open", + "locked": false, + "title": "Update the README with new information", + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "body": "This is a pretty simple change that we need to pull into master.", + "created_at": "2015-05-05T23:40:27Z", + "updated_at": "2015-05-05T23:40:27Z", + "closed_at": null, + "merged_at": null, + "merge_commit_sha": "18721552ba489fb84e12958c1b5694b5475f7991", + "assignee": null, + "milestone": null, + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1/commits", + "review_comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1/comments", + "review_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/1/comments", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "head": { + "label": "baxterthehacker:changes", + "ref": "changes", + "sha": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:27Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 1, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "master" + } + }, + "base": { + "label": "baxterthehacker:master", + "ref": "master", + "sha": "9049f1265b7d61be4a8904a9a27120d2064dab3b", + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:27Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 1, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "master" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1" + }, + "html": { + "href": "https://github.com/baxterthehacker/public-repo/pull/1" + }, + "issue": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/issues/1" + }, + "comments": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/issues/1/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c" + } + } + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:27Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 1, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +}` +} + +func PullRequestEventJSON() string { + return `{ + "action": "opened", + "number": 1, + "pull_request": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1", + "id": 34778301, + "html_url": "https://github.com/baxterthehacker/public-repo/pull/1", + "diff_url": "https://github.com/baxterthehacker/public-repo/pull/1.diff", + "patch_url": "https://github.com/baxterthehacker/public-repo/pull/1.patch", + "issue_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/1", + "number": 1, + "state": "open", + "locked": false, + "title": "Update the README with new information", + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "body": "This is a pretty simple change that we need to pull into master.", + "created_at": "2015-05-05T23:40:27Z", + "updated_at": "2015-05-05T23:40:27Z", + "closed_at": null, + "merged_at": null, + "merge_commit_sha": null, + "assignee": null, + "milestone": null, + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1/commits", + "review_comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1/comments", + "review_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/1/comments", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "head": { + "label": "baxterthehacker:changes", + "ref": "changes", + "sha": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:26Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 1, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "master" + } + }, + "base": { + "label": "baxterthehacker:master", + "ref": "master", + "sha": "9049f1265b7d61be4a8904a9a27120d2064dab3b", + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:26Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 1, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "master" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1" + }, + "html": { + "href": "https://github.com/baxterthehacker/public-repo/pull/1" + }, + "issue": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/issues/1" + }, + "comments": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/issues/1/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c" + } + }, + "merged": false, + "mergeable": null, + "mergeable_state": "unknown", + "merged_by": null, + "comments": 0, + "review_comments": 0, + "commits": 1, + "additions": 1, + "deletions": 1, + "changed_files": 1 + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:26Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 1, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +}` +} + +func PushEventJSON() string { + return `{ + "ref": "refs/heads/changes", + "before": "9049f1265b7d61be4a8904a9a27120d2064dab3b", + "after": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "created": false, + "deleted": false, + "forced": false, + "base_ref": null, + "compare": "https://github.com/baxterthehacker/public-repo/compare/9049f1265b7d...0d1a26e67d8f", + "commits": [ + { + "id": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "distinct": true, + "message": "Update README.md", + "timestamp": "2015-05-05T19:40:15-04:00", + "url": "https://github.com/baxterthehacker/public-repo/commit/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "author": { + "name": "baxterthehacker", + "email": "baxterthehacker@users.noreply.github.com", + "username": "baxterthehacker" + }, + "committer": { + "name": "baxterthehacker", + "email": "baxterthehacker@users.noreply.github.com", + "username": "baxterthehacker" + }, + "added": [ + + ], + "removed": [ + + ], + "modified": [ + "README.md" + ] + } + ], + "head_commit": { + "id": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "distinct": true, + "message": "Update README.md", + "timestamp": "2015-05-05T19:40:15-04:00", + "url": "https://github.com/baxterthehacker/public-repo/commit/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "author": { + "name": "baxterthehacker", + "email": "baxterthehacker@users.noreply.github.com", + "username": "baxterthehacker" + }, + "committer": { + "name": "baxterthehacker", + "email": "baxterthehacker@users.noreply.github.com", + "username": "baxterthehacker" + }, + "added": [ + + ], + "removed": [ + + ], + "modified": [ + "README.md" + ] + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "name": "baxterthehacker", + "email": "baxterthehacker@users.noreply.github.com" + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://github.com/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": 1430869212, + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": 1430869217, + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 0, + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "master", + "stargazers": 0, + "master_branch": "master" + }, + "pusher": { + "name": "baxterthehacker", + "email": "baxterthehacker@users.noreply.github.com" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +}` +} + +func RepositoryEventJSON() string { + return `{ + "action": "created", + "repository": { + "id": 27496774, + "name": "new-repository", + "full_name": "baxterandthehackers/new-repository", + "owner": { + "login": "baxterandthehackers", + "id": 7649605, + "avatar_url": "https://avatars.githubusercontent.com/u/7649605?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterandthehackers", + "html_url": "https://github.com/baxterandthehackers", + "followers_url": "https://api.github.com/users/baxterandthehackers/followers", + "following_url": "https://api.github.com/users/baxterandthehackers/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterandthehackers/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterandthehackers/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterandthehackers/subscriptions", + "organizations_url": "https://api.github.com/users/baxterandthehackers/orgs", + "repos_url": "https://api.github.com/users/baxterandthehackers/repos", + "events_url": "https://api.github.com/users/baxterandthehackers/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterandthehackers/received_events", + "type": "Organization", + "site_admin": false + }, + "private": true, + "html_url": "https://github.com/baxterandthehackers/new-repository", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterandthehackers/new-repository", + "forks_url": "https://api.github.com/repos/baxterandthehackers/new-repository/forks", + "keys_url": "https://api.github.com/repos/baxterandthehackers/new-repository/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterandthehackers/new-repository/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterandthehackers/new-repository/teams", + "hooks_url": "https://api.github.com/repos/baxterandthehackers/new-repository/hooks", + "issue_events_url": "https://api.github.com/repos/baxterandthehackers/new-repository/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterandthehackers/new-repository/events", + "assignees_url": "https://api.github.com/repos/baxterandthehackers/new-repository/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterandthehackers/new-repository/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterandthehackers/new-repository/tags", + "blobs_url": "https://api.github.com/repos/baxterandthehackers/new-repository/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterandthehackers/new-repository/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterandthehackers/new-repository/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterandthehackers/new-repository/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterandthehackers/new-repository/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterandthehackers/new-repository/languages", + "stargazers_url": "https://api.github.com/repos/baxterandthehackers/new-repository/stargazers", + "contributors_url": "https://api.github.com/repos/baxterandthehackers/new-repository/contributors", + "subscribers_url": "https://api.github.com/repos/baxterandthehackers/new-repository/subscribers", + "subscription_url": "https://api.github.com/repos/baxterandthehackers/new-repository/subscription", + "commits_url": "https://api.github.com/repos/baxterandthehackers/new-repository/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterandthehackers/new-repository/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterandthehackers/new-repository/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterandthehackers/new-repository/issues/comments/{number}", + "contents_url": "https://api.github.com/repos/baxterandthehackers/new-repository/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterandthehackers/new-repository/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterandthehackers/new-repository/merges", + "archive_url": "https://api.github.com/repos/baxterandthehackers/new-repository/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterandthehackers/new-repository/downloads", + "issues_url": "https://api.github.com/repos/baxterandthehackers/new-repository/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterandthehackers/new-repository/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterandthehackers/new-repository/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterandthehackers/new-repository/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterandthehackers/new-repository/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterandthehackers/new-repository/releases{/id}", + "created_at": "2014-12-03T16:39:25Z", + "updated_at": "2014-12-03T16:39:25Z", + "pushed_at": "2014-12-03T16:39:25Z", + "git_url": "git://github.com/baxterandthehackers/new-repository.git", + "ssh_url": "git@github.com:baxterandthehackers/new-repository.git", + "clone_url": "https://github.com/baxterandthehackers/new-repository.git", + "svn_url": "https://github.com/baxterandthehackers/new-repository", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 0, + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "master" + }, + "organization": { + "login": "baxterandthehackers", + "id": 7649605, + "url": "https://api.github.com/orgs/baxterandthehackers", + "repos_url": "https://api.github.com/orgs/baxterandthehackers/repos", + "events_url": "https://api.github.com/orgs/baxterandthehackers/events", + "members_url": "https://api.github.com/orgs/baxterandthehackers/members{/member}", + "public_members_url": "https://api.github.com/orgs/baxterandthehackers/public_members{/member}", + "avatar_url": "https://avatars.githubusercontent.com/u/7649605?v=2" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=2", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +}` +} + +func ReleaseEventJSON() string { + return `{ + "action": "published", + "release": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/releases/1261438", + "assets_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases/1261438/assets", + "upload_url": "https://uploads.github.com/repos/baxterthehacker/public-repo/releases/1261438/assets{?name}", + "html_url": "https://github.com/baxterthehacker/public-repo/releases/tag/0.0.1", + "id": 1261438, + "tag_name": "0.0.1", + "target_commitish": "master", + "name": null, + "draft": false, + "author": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "prerelease": false, + "created_at": "2015-05-05T23:40:12Z", + "published_at": "2015-05-05T23:40:38Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/baxterthehacker/public-repo/tarball/0.0.1", + "zipball_url": "https://api.github.com/repos/baxterthehacker/public-repo/zipball/0.0.1", + "body": null + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:38Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +}` +} + +func StatusEventJSON() string { + return `{ + "id": 214015194, + "sha": "9049f1265b7d61be4a8904a9a27120d2064dab3b", + "name": "baxterthehacker/public-repo", + "target_url": null, + "context": "default", + "description": null, + "state": "success", + "commit": { + "sha": "9049f1265b7d61be4a8904a9a27120d2064dab3b", + "commit": { + "author": { + "name": "baxterthehacker", + "email": "baxterthehacker@users.noreply.github.com", + "date": "2015-05-05T23:40:12Z" + }, + "committer": { + "name": "baxterthehacker", + "email": "baxterthehacker@users.noreply.github.com", + "date": "2015-05-05T23:40:12Z" + }, + "message": "Initial commit", + "tree": { + "sha": "02b49ad0ba4f1acd9f06531b21e16a4ac5d341d0", + "url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees/02b49ad0ba4f1acd9f06531b21e16a4ac5d341d0" + }, + "url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits/9049f1265b7d61be4a8904a9a27120d2064dab3b", + "comment_count": 1 + }, + "url": "https://api.github.com/repos/baxterthehacker/public-repo/commits/9049f1265b7d61be4a8904a9a27120d2064dab3b", + "html_url": "https://github.com/baxterthehacker/public-repo/commit/9049f1265b7d61be4a8904a9a27120d2064dab3b", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits/9049f1265b7d61be4a8904a9a27120d2064dab3b/comments", + "author": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "committer": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "parents": [ + + ] + }, + "branches": [ + { + "name": "master", + "commit": { + "sha": "9049f1265b7d61be4a8904a9a27120d2064dab3b", + "url": "https://api.github.com/repos/baxterthehacker/public-repo/commits/9049f1265b7d61be4a8904a9a27120d2064dab3b" + } + }, + { + "name": "changes", + "commit": { + "sha": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "url": "https://api.github.com/repos/baxterthehacker/public-repo/commits/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c" + } + }, + { + "name": "gh-pages", + "commit": { + "sha": "b11bb7545ac14abafc6191a0481b0d961e7793c6", + "url": "https://api.github.com/repos/baxterthehacker/public-repo/commits/b11bb7545ac14abafc6191a0481b0d961e7793c6" + } + } + ], + "created_at": "2015-05-05T23:40:39Z", + "updated_at": "2015-05-05T23:40:39Z", + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:39Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +}` +} + +func TeamAddEventJSON() string { + return `{ + "team": { + "name": "github", + "id": 836012, + "slug": "github", + "description": "", + "permission": "pull", + "url": "https://api.github.com/teams/836012", + "members_url": "https://api.github.com/teams/836012/members{/member}", + "repositories_url": "https://api.github.com/teams/836012/repos" + }, + "repository": { + "id": 35129393, + "name": "public-repo", + "full_name": "baxterandthehackers/public-repo", + "owner": { + "login": "baxterandthehackers", + "id": 7649605, + "avatar_url": "https://avatars.githubusercontent.com/u/7649605?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterandthehackers", + "html_url": "https://github.com/baxterandthehackers", + "followers_url": "https://api.github.com/users/baxterandthehackers/followers", + "following_url": "https://api.github.com/users/baxterandthehackers/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterandthehackers/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterandthehackers/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterandthehackers/subscriptions", + "organizations_url": "https://api.github.com/users/baxterandthehackers/orgs", + "repos_url": "https://api.github.com/users/baxterandthehackers/repos", + "events_url": "https://api.github.com/users/baxterandthehackers/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterandthehackers/received_events", + "type": "Organization", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterandthehackers/public-repo", + "description": "", + "fork": true, + "url": "https://api.github.com/repos/baxterandthehackers/public-repo", + "forks_url": "https://api.github.com/repos/baxterandthehackers/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterandthehackers/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterandthehackers/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterandthehackers/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterandthehackers/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterandthehackers/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterandthehackers/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterandthehackers/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterandthehackers/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterandthehackers/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterandthehackers/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterandthehackers/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterandthehackers/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterandthehackers/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterandthehackers/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterandthehackers/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterandthehackers/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterandthehackers/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterandthehackers/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterandthehackers/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterandthehackers/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterandthehackers/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterandthehackers/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterandthehackers/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterandthehackers/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterandthehackers/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterandthehackers/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterandthehackers/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterandthehackers/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterandthehackers/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:30Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:27Z", + "git_url": "git://github.com/baxterandthehackers/public-repo.git", + "ssh_url": "git@github.com:baxterandthehackers/public-repo.git", + "clone_url": "https://github.com/baxterandthehackers/public-repo.git", + "svn_url": "https://github.com/baxterandthehackers/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": false, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 0, + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "master" + }, + "organization": { + "login": "baxterandthehackers", + "id": 7649605, + "url": "https://api.github.com/orgs/baxterandthehackers", + "repos_url": "https://api.github.com/orgs/baxterandthehackers/repos", + "events_url": "https://api.github.com/orgs/baxterandthehackers/events", + "members_url": "https://api.github.com/orgs/baxterandthehackers/members{/member}", + "public_members_url": "https://api.github.com/orgs/baxterandthehackers/public_members{/member}", + "avatar_url": "https://avatars.githubusercontent.com/u/7649605?v=3", + "description": null + }, + "sender": { + "login": "baxterandthehackers", + "id": 7649605, + "avatar_url": "https://avatars.githubusercontent.com/u/7649605?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterandthehackers", + "html_url": "https://github.com/baxterandthehackers", + "followers_url": "https://api.github.com/users/baxterandthehackers/followers", + "following_url": "https://api.github.com/users/baxterandthehackers/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterandthehackers/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterandthehackers/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterandthehackers/subscriptions", + "organizations_url": "https://api.github.com/users/baxterandthehackers/orgs", + "repos_url": "https://api.github.com/users/baxterandthehackers/repos", + "events_url": "https://api.github.com/users/baxterandthehackers/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterandthehackers/received_events", + "type": "Organization", + "site_admin": false + } +}` +} + +func WatchEventJSON() string { + return `{ + "action": "started", + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:27Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +}` +} diff --git a/plugins/inputs/github_webhooks/github_webhooks_models.go b/plugins/inputs/github_webhooks/github_webhooks_models.go new file mode 100644 index 000000000..16acad6b5 --- /dev/null +++ b/plugins/inputs/github_webhooks/github_webhooks_models.go @@ -0,0 +1,711 @@ +package github_webhooks + +import ( + "fmt" + "log" + "time" + + "github.com/influxdata/influxdb/client/v2" +) + +const meas = "github_webhooks" + +type Event interface { + NewPoint() *client.Point +} + +type Repository struct { + Repository string `json:"full_name"` + Private bool `json:"private"` + Stars int `json:"stargazers_count"` + Forks int `json:"forks_count"` + Issues int `json:"open_issues_count"` +} + +type Sender struct { + User string `json:"login"` + Admin bool `json:"site_admin"` +} + +type CommitComment struct { + Commit string `json:"commit_id"` + Body string `json:"body"` +} + +type Deployment struct { + Commit string `json:"sha"` + Task string `json:"task"` + Environment string `json:"environment"` + Description string `json:"description"` +} + +type Page struct { + Name string `json:"page_name"` + Title string `json:"title"` + Action string `json:"action"` +} + +type Issue struct { + Number int `json:"number"` + Title string `json:"title"` + Comments int `json:"comments"` +} + +type IssueComment struct { + Body string `json:"body"` +} + +type Team struct { + Name string `json:"name"` +} + +type PullRequest struct { + Number int `json:"number"` + State string `json:"state"` + Title string `json:"title"` + Comments int `json:"comments"` + Commits int `json:"commits"` + Additions int `json:"additions"` + Deletions int `json:"deletions"` + ChangedFiles int `json:"changed_files"` +} + +type PullRequestReviewComment struct { + File string `json:"path"` + Comment string `json:"body"` +} + +type Release struct { + TagName string `json:"tag_name"` +} + +type DeploymentStatus struct { + State string `json:"state"` + Description string `json:"description"` +} + +type CommitCommentEvent struct { + Comment CommitComment `json:"comment"` + Repository Repository `json:"repository"` + Sender Sender `json:"sender"` +} + +func (s CommitCommentEvent) NewPoint() *client.Point { + event := "commit_comment" + t := map[string]string{ + "event": event, + "repository": s.Repository.Repository, + "private": fmt.Sprintf("%v", s.Repository.Private), + "user": s.Sender.User, + "admin": fmt.Sprintf("%v", s.Sender.Admin), + } + f := map[string]interface{}{ + "stars": s.Repository.Stars, + "forks": s.Repository.Forks, + "issues": s.Repository.Issues, + "commit": s.Comment.Commit, + "comment": s.Comment.Body, + } + p, err := client.NewPoint(meas, t, f, time.Now()) + if err != nil { + log.Fatalf("Failed to create %v event", event) + } + return p +} + +type CreateEvent struct { + Ref string `json:"ref"` + RefType string `json:"ref_type"` + Repository Repository `json:"repository"` + Sender Sender `json:"sender"` +} + +func (s CreateEvent) NewPoint() *client.Point { + event := "create" + t := map[string]string{ + "event": event, + "repository": s.Repository.Repository, + "private": fmt.Sprintf("%v", s.Repository.Private), + "user": s.Sender.User, + "admin": fmt.Sprintf("%v", s.Sender.Admin), + } + f := map[string]interface{}{ + "stars": s.Repository.Stars, + "forks": s.Repository.Forks, + "issues": s.Repository.Issues, + "ref": s.Ref, + "refType": s.RefType, + } + p, err := client.NewPoint(meas, t, f, time.Now()) + if err != nil { + log.Fatalf("Failed to create %v event", event) + } + return p +} + +type DeleteEvent struct { + Ref string `json:"ref"` + RefType string `json:"ref_type"` + Repository Repository `json:"repository"` + Sender Sender `json:"sender"` +} + +func (s DeleteEvent) NewPoint() *client.Point { + event := "delete" + t := map[string]string{ + "event": event, + "repository": s.Repository.Repository, + "private": fmt.Sprintf("%v", s.Repository.Private), + "user": s.Sender.User, + "admin": fmt.Sprintf("%v", s.Sender.Admin), + } + f := map[string]interface{}{ + "stars": s.Repository.Stars, + "forks": s.Repository.Forks, + "issues": s.Repository.Issues, + "ref": s.Ref, + "refType": s.RefType, + } + p, err := client.NewPoint(meas, t, f, time.Now()) + if err != nil { + log.Fatalf("Failed to create %v event", event) + } + return p +} + +type DeploymentEvent struct { + Deployment Deployment `json:"deployment"` + Repository Repository `json:"repository"` + Sender Sender `json:"sender"` +} + +func (s DeploymentEvent) NewPoint() *client.Point { + event := "deployment" + t := map[string]string{ + "event": event, + "repository": s.Repository.Repository, + "private": fmt.Sprintf("%v", s.Repository.Private), + "user": s.Sender.User, + "admin": fmt.Sprintf("%v", s.Sender.Admin), + } + f := map[string]interface{}{ + "stars": s.Repository.Stars, + "forks": s.Repository.Forks, + "issues": s.Repository.Issues, + "commit": s.Deployment.Commit, + "task": s.Deployment.Task, + "environment": s.Deployment.Environment, + "description": s.Deployment.Description, + } + p, err := client.NewPoint(meas, t, f, time.Now()) + if err != nil { + log.Fatalf("Failed to create %v event", event) + } + return p +} + +type DeploymentStatusEvent struct { + Deployment Deployment `json:"deployment"` + DeploymentStatus DeploymentStatus `json:"deployment_status"` + Repository Repository `json:"repository"` + Sender Sender `json:"sender"` +} + +func (s DeploymentStatusEvent) NewPoint() *client.Point { + event := "delete" + t := map[string]string{ + "event": event, + "repository": s.Repository.Repository, + "private": fmt.Sprintf("%v", s.Repository.Private), + "user": s.Sender.User, + "admin": fmt.Sprintf("%v", s.Sender.Admin), + } + f := map[string]interface{}{ + "stars": s.Repository.Stars, + "forks": s.Repository.Forks, + "issues": s.Repository.Issues, + "commit": s.Deployment.Commit, + "task": s.Deployment.Task, + "environment": s.Deployment.Environment, + "description": s.Deployment.Description, + "depState": s.DeploymentStatus.State, + "depDescription": s.DeploymentStatus.Description, + } + p, err := client.NewPoint(meas, t, f, time.Now()) + if err != nil { + log.Fatalf("Failed to create %v event", event) + } + return p +} + +type ForkEvent struct { + Forkee Repository `json:"forkee"` + Repository Repository `json:"repository"` + Sender Sender `json:"sender"` +} + +func (s ForkEvent) NewPoint() *client.Point { + event := "fork" + t := map[string]string{ + "event": event, + "repository": s.Repository.Repository, + "private": fmt.Sprintf("%v", s.Repository.Private), + "user": s.Sender.User, + "admin": fmt.Sprintf("%v", s.Sender.Admin), + } + f := map[string]interface{}{ + "stars": s.Repository.Stars, + "forks": s.Repository.Forks, + "issues": s.Repository.Issues, + "fork": s.Forkee.Repository, + } + p, err := client.NewPoint(meas, t, f, time.Now()) + if err != nil { + log.Fatalf("Failed to create %v event", event) + } + return p +} + +type GollumEvent struct { + Pages []Page `json:"pages"` + Repository Repository `json:"repository"` + Sender Sender `json:"sender"` +} + +// REVIEW: Going to be lazy and not deal with the pages. +func (s GollumEvent) NewPoint() *client.Point { + event := "gollum" + t := map[string]string{ + "event": event, + "repository": s.Repository.Repository, + "private": fmt.Sprintf("%v", s.Repository.Private), + "user": s.Sender.User, + "admin": fmt.Sprintf("%v", s.Sender.Admin), + } + f := map[string]interface{}{ + "stars": s.Repository.Stars, + "forks": s.Repository.Forks, + "issues": s.Repository.Issues, + } + p, err := client.NewPoint(meas, t, f, time.Now()) + if err != nil { + log.Fatalf("Failed to create %v event", event) + } + return p +} + +type IssueCommentEvent struct { + Issue Issue `json:"issue"` + Comment IssueComment `json:"comment"` + Repository Repository `json:"repository"` + Sender Sender `json:"sender"` +} + +func (s IssueCommentEvent) NewPoint() *client.Point { + event := "issue_comment" + t := map[string]string{ + "event": event, + "repository": s.Repository.Repository, + "private": fmt.Sprintf("%v", s.Repository.Private), + "user": s.Sender.User, + "admin": fmt.Sprintf("%v", s.Sender.Admin), + "issue": fmt.Sprintf("%v", s.Issue.Number), + } + f := map[string]interface{}{ + "stars": s.Repository.Stars, + "forks": s.Repository.Forks, + "issues": s.Repository.Issues, + "title": s.Issue.Title, + "comments": s.Issue.Comments, + "body": s.Comment.Body, + } + p, err := client.NewPoint(meas, t, f, time.Now()) + if err != nil { + log.Fatalf("Failed to create %v event", event) + } + return p +} + +type IssuesEvent struct { + Action string `json:"action"` + Issue Issue `json:"issue"` + Repository Repository `json:"repository"` + Sender Sender `json:"sender"` +} + +func (s IssuesEvent) NewPoint() *client.Point { + event := "issue" + t := map[string]string{ + "event": event, + "repository": s.Repository.Repository, + "private": fmt.Sprintf("%v", s.Repository.Private), + "user": s.Sender.User, + "admin": fmt.Sprintf("%v", s.Sender.Admin), + "issue": fmt.Sprintf("%v", s.Issue.Number), + "action": s.Action, + } + f := map[string]interface{}{ + "stars": s.Repository.Stars, + "forks": s.Repository.Forks, + "issues": s.Repository.Issues, + "title": s.Issue.Title, + "comments": s.Issue.Comments, + } + p, err := client.NewPoint(meas, t, f, time.Now()) + if err != nil { + log.Fatalf("Failed to create %v event", event) + } + return p +} + +type MemberEvent struct { + Member Sender `json:"member"` + Repository Repository `json:"repository"` + Sender Sender `json:"sender"` +} + +func (s MemberEvent) NewPoint() *client.Point { + event := "member" + t := map[string]string{ + "event": event, + "repository": s.Repository.Repository, + "private": fmt.Sprintf("%v", s.Repository.Private), + "user": s.Sender.User, + "admin": fmt.Sprintf("%v", s.Sender.Admin), + } + f := map[string]interface{}{ + "stars": s.Repository.Stars, + "forks": s.Repository.Forks, + "issues": s.Repository.Issues, + "newMember": s.Member.User, + "newMemberStatus": s.Member.Admin, + } + p, err := client.NewPoint(meas, t, f, time.Now()) + if err != nil { + log.Fatalf("Failed to create %v event", event) + } + return p +} + +type MembershipEvent struct { + Action string `json:"action"` + Member Sender `json:"member"` + Sender Sender `json:"sender"` + Team Team `json:"team"` +} + +func (s MembershipEvent) NewPoint() *client.Point { + event := "membership" + t := map[string]string{ + "event": event, + "user": s.Sender.User, + "admin": fmt.Sprintf("%v", s.Sender.Admin), + "action": s.Action, + } + f := map[string]interface{}{ + "newMember": s.Member.User, + "newMemberStatus": s.Member.Admin, + } + p, err := client.NewPoint(meas, t, f, time.Now()) + if err != nil { + log.Fatalf("Failed to create %v event", event) + } + return p +} + +type PageBuildEvent struct { + Repository Repository `json:"repository"` + Sender Sender `json:"sender"` +} + +func (s PageBuildEvent) NewPoint() *client.Point { + event := "page_build" + t := map[string]string{ + "event": event, + "repository": s.Repository.Repository, + "private": fmt.Sprintf("%v", s.Repository.Private), + "user": s.Sender.User, + "admin": fmt.Sprintf("%v", s.Sender.Admin), + } + f := map[string]interface{}{ + "stars": s.Repository.Stars, + "forks": s.Repository.Forks, + "issues": s.Repository.Issues, + } + p, err := client.NewPoint(meas, t, f, time.Now()) + if err != nil { + log.Fatalf("Failed to create %v event", event) + } + return p +} + +type PublicEvent struct { + Repository Repository `json:"repository"` + Sender Sender `json:"sender"` +} + +func (s PublicEvent) NewPoint() *client.Point { + event := "public" + t := map[string]string{ + "event": event, + "repository": s.Repository.Repository, + "private": fmt.Sprintf("%v", s.Repository.Private), + "user": s.Sender.User, + "admin": fmt.Sprintf("%v", s.Sender.Admin), + } + f := map[string]interface{}{ + "stars": s.Repository.Stars, + "forks": s.Repository.Forks, + "issues": s.Repository.Issues, + } + p, err := client.NewPoint(meas, t, f, time.Now()) + if err != nil { + log.Fatalf("Failed to create %v event", event) + } + return p +} + +type PullRequestEvent struct { + Action string `json:"action"` + PullRequest PullRequest `json:"pull_request"` + Repository Repository `json:"repository"` + Sender Sender `json:"sender"` +} + +func (s PullRequestEvent) NewPoint() *client.Point { + event := "pull_request" + t := map[string]string{ + "event": event, + "action": s.Action, + "repository": s.Repository.Repository, + "private": fmt.Sprintf("%v", s.Repository.Private), + "user": s.Sender.User, + "admin": fmt.Sprintf("%v", s.Sender.Admin), + "prNumber": fmt.Sprintf("%v", s.PullRequest.Number), + } + f := map[string]interface{}{ + "stars": s.Repository.Stars, + "forks": s.Repository.Forks, + "issues": s.Repository.Issues, + "state": s.PullRequest.State, + "title": s.PullRequest.Title, + "comments": s.PullRequest.Comments, + "commits": s.PullRequest.Commits, + "additions": s.PullRequest.Additions, + "deletions": s.PullRequest.Deletions, + "changedFiles": s.PullRequest.ChangedFiles, + } + p, err := client.NewPoint(meas, t, f, time.Now()) + if err != nil { + log.Fatalf("Failed to create %v event", event) + } + return p +} + +type PullRequestReviewCommentEvent struct { + Comment PullRequestReviewComment `json:"comment"` + PullRequest PullRequest `json:"pull_request"` + Repository Repository `json:"repository"` + Sender Sender `json:"sender"` +} + +func (s PullRequestReviewCommentEvent) NewPoint() *client.Point { + event := "pull_request_review_comment" + t := map[string]string{ + "event": event, + "repository": s.Repository.Repository, + "private": fmt.Sprintf("%v", s.Repository.Private), + "user": s.Sender.User, + "admin": fmt.Sprintf("%v", s.Sender.Admin), + "prNumber": fmt.Sprintf("%v", s.PullRequest.Number), + } + f := map[string]interface{}{ + "stars": s.Repository.Stars, + "forks": s.Repository.Forks, + "issues": s.Repository.Issues, + "state": s.PullRequest.State, + "title": s.PullRequest.Title, + "comments": s.PullRequest.Comments, + "commits": s.PullRequest.Commits, + "additions": s.PullRequest.Additions, + "deletions": s.PullRequest.Deletions, + "changedFiles": s.PullRequest.ChangedFiles, + "commentFile": s.Comment.File, + "comment": s.Comment.Comment, + } + p, err := client.NewPoint(meas, t, f, time.Now()) + if err != nil { + log.Fatalf("Failed to create %v event", event) + } + return p +} + +type PushEvent struct { + Ref string `json:"ref"` + Before string `json:"before"` + After string `json:"after"` + Repository Repository `json:"repository"` + Sender Sender `json:"sender"` +} + +func (s PushEvent) NewPoint() *client.Point { + event := "push" + t := map[string]string{ + "event": event, + "repository": s.Repository.Repository, + "private": fmt.Sprintf("%v", s.Repository.Private), + "user": s.Sender.User, + "admin": fmt.Sprintf("%v", s.Sender.Admin), + } + f := map[string]interface{}{ + "stars": s.Repository.Stars, + "forks": s.Repository.Forks, + "issues": s.Repository.Issues, + "ref": s.Ref, + "before": s.Before, + "after": s.After, + } + p, err := client.NewPoint(meas, t, f, time.Now()) + if err != nil { + log.Fatalf("Failed to create %v event", event) + } + return p +} + +type ReleaseEvent struct { + Release Release `json:"release"` + Repository Repository `json:"repository"` + Sender Sender `json:"sender"` +} + +func (s ReleaseEvent) NewPoint() *client.Point { + event := "release" + t := map[string]string{ + "event": event, + "repository": s.Repository.Repository, + "private": fmt.Sprintf("%v", s.Repository.Private), + "user": s.Sender.User, + "admin": fmt.Sprintf("%v", s.Sender.Admin), + } + f := map[string]interface{}{ + "stars": s.Repository.Stars, + "forks": s.Repository.Forks, + "issues": s.Repository.Issues, + "tagName": s.Release.TagName, + } + p, err := client.NewPoint(meas, t, f, time.Now()) + if err != nil { + log.Fatalf("Failed to create %v event", event) + } + return p +} + +type RepositoryEvent struct { + Repository Repository `json:"repository"` + Sender Sender `json:"sender"` +} + +func (s RepositoryEvent) NewPoint() *client.Point { + event := "repository" + t := map[string]string{ + "event": event, + "repository": s.Repository.Repository, + "private": fmt.Sprintf("%v", s.Repository.Private), + "user": s.Sender.User, + "admin": fmt.Sprintf("%v", s.Sender.Admin), + } + f := map[string]interface{}{ + "stars": s.Repository.Stars, + "forks": s.Repository.Forks, + "issues": s.Repository.Issues, + } + p, err := client.NewPoint(meas, t, f, time.Now()) + if err != nil { + log.Fatalf("Failed to create %v event", event) + } + return p +} + +type StatusEvent struct { + Commit string `json:"sha"` + State string `json:"state"` + Repository Repository `json:"repository"` + Sender Sender `json:"sender"` +} + +func (s StatusEvent) NewPoint() *client.Point { + event := "status" + t := map[string]string{ + "event": event, + "repository": s.Repository.Repository, + "private": fmt.Sprintf("%v", s.Repository.Private), + "user": s.Sender.User, + "admin": fmt.Sprintf("%v", s.Sender.Admin), + } + f := map[string]interface{}{ + "stars": s.Repository.Stars, + "forks": s.Repository.Forks, + "issues": s.Repository.Issues, + "commit": s.Commit, + "state": s.State, + } + p, err := client.NewPoint(meas, t, f, time.Now()) + if err != nil { + log.Fatalf("Failed to create %v event", event) + } + return p +} + +type TeamAddEvent struct { + Team Team `json:"team"` + Repository Repository `json:"repository"` + Sender Sender `json:"sender"` +} + +func (s TeamAddEvent) NewPoint() *client.Point { + event := "team_add" + t := map[string]string{ + "event": event, + "repository": s.Repository.Repository, + "private": fmt.Sprintf("%v", s.Repository.Private), + "user": s.Sender.User, + "admin": fmt.Sprintf("%v", s.Sender.Admin), + } + f := map[string]interface{}{ + "stars": s.Repository.Stars, + "forks": s.Repository.Forks, + "issues": s.Repository.Issues, + "teamName": s.Team.Name, + } + p, err := client.NewPoint(meas, t, f, time.Now()) + if err != nil { + log.Fatalf("Failed to create %v event", event) + } + return p +} + +type WatchEvent struct { + Repository Repository `json:"repository"` + Sender Sender `json:"sender"` +} + +func (s WatchEvent) NewPoint() *client.Point { + event := "delete" + t := map[string]string{ + "event": event, + "repository": s.Repository.Repository, + "private": fmt.Sprintf("%v", s.Repository.Private), + "user": s.Sender.User, + "admin": fmt.Sprintf("%v", s.Sender.Admin), + } + f := map[string]interface{}{ + "stars": s.Repository.Stars, + "forks": s.Repository.Forks, + "issues": s.Repository.Issues, + } + p, err := client.NewPoint(meas, t, f, time.Now()) + if err != nil { + log.Fatalf("Failed to create %v event", event) + } + return p +} diff --git a/plugins/inputs/github_webhooks/github_webhooks_test.go b/plugins/inputs/github_webhooks/github_webhooks_test.go new file mode 100644 index 000000000..7b0631990 --- /dev/null +++ b/plugins/inputs/github_webhooks/github_webhooks_test.go @@ -0,0 +1,237 @@ +package github_webhooks + +import ( + "net/http" + "net/http/httptest" + "strings" + "testing" +) + +func TestCommitCommentEvent(t *testing.T) { + gh := NewGithubWebhooks() + jsonString := CommitCommentEventJSON() + req, _ := http.NewRequest("POST", "/", strings.NewReader(jsonString)) + req.Header.Add("X-Github-Event", "commit_comment") + w := httptest.NewRecorder() + gh.eventHandler(w, req) + if w.Code != http.StatusOK { + t.Errorf("POST commit_comment returned HTTP status code %v.\nExpected %v", w.Code, http.StatusOK) + } +} + +func TestDeleteEvent(t *testing.T) { + gh := NewGithubWebhooks() + jsonString := DeleteEventJSON() + req, _ := http.NewRequest("POST", "/", strings.NewReader(jsonString)) + req.Header.Add("X-Github-Event", "delete") + w := httptest.NewRecorder() + gh.eventHandler(w, req) + if w.Code != http.StatusOK { + t.Errorf("POST commit_comment returned HTTP status code %v.\nExpected %v", w.Code, http.StatusOK) + } +} + +func TestDeploymentEvent(t *testing.T) { + gh := NewGithubWebhooks() + jsonString := DeploymentEventJSON() + req, _ := http.NewRequest("POST", "/", strings.NewReader(jsonString)) + req.Header.Add("X-Github-Event", "deployment") + w := httptest.NewRecorder() + gh.eventHandler(w, req) + if w.Code != http.StatusOK { + t.Errorf("POST commit_comment returned HTTP status code %v.\nExpected %v", w.Code, http.StatusOK) + } +} + +func TestDeploymentStatusEvent(t *testing.T) { + gh := NewGithubWebhooks() + jsonString := DeploymentStatusEventJSON() + req, _ := http.NewRequest("POST", "/", strings.NewReader(jsonString)) + req.Header.Add("X-Github-Event", "deployment_status") + w := httptest.NewRecorder() + gh.eventHandler(w, req) + if w.Code != http.StatusOK { + t.Errorf("POST commit_comment returned HTTP status code %v.\nExpected %v", w.Code, http.StatusOK) + } +} + +func TestForkEvent(t *testing.T) { + gh := NewGithubWebhooks() + jsonString := ForkEventJSON() + req, _ := http.NewRequest("POST", "/", strings.NewReader(jsonString)) + req.Header.Add("X-Github-Event", "fork") + w := httptest.NewRecorder() + gh.eventHandler(w, req) + if w.Code != http.StatusOK { + t.Errorf("POST commit_comment returned HTTP status code %v.\nExpected %v", w.Code, http.StatusOK) + } +} + +func TestGollumEvent(t *testing.T) { + gh := NewGithubWebhooks() + jsonString := GollumEventJSON() + req, _ := http.NewRequest("POST", "/", strings.NewReader(jsonString)) + req.Header.Add("X-Github-Event", "gollum") + w := httptest.NewRecorder() + gh.eventHandler(w, req) + if w.Code != http.StatusOK { + t.Errorf("POST commit_comment returned HTTP status code %v.\nExpected %v", w.Code, http.StatusOK) + } +} + +func TestIssueCommentEvent(t *testing.T) { + gh := NewGithubWebhooks() + jsonString := IssueCommentEventJSON() + req, _ := http.NewRequest("POST", "/", strings.NewReader(jsonString)) + req.Header.Add("X-Github-Event", "issue_comment") + w := httptest.NewRecorder() + gh.eventHandler(w, req) + if w.Code != http.StatusOK { + t.Errorf("POST commit_comment returned HTTP status code %v.\nExpected %v", w.Code, http.StatusOK) + } +} + +func TestIssuesEvent(t *testing.T) { + gh := NewGithubWebhooks() + jsonString := IssuesEventJSON() + req, _ := http.NewRequest("POST", "/", strings.NewReader(jsonString)) + req.Header.Add("X-Github-Event", "issues") + w := httptest.NewRecorder() + gh.eventHandler(w, req) + if w.Code != http.StatusOK { + t.Errorf("POST commit_comment returned HTTP status code %v.\nExpected %v", w.Code, http.StatusOK) + } +} + +func TestMemberEvent(t *testing.T) { + gh := NewGithubWebhooks() + jsonString := MemberEventJSON() + req, _ := http.NewRequest("POST", "/", strings.NewReader(jsonString)) + req.Header.Add("X-Github-Event", "member") + w := httptest.NewRecorder() + gh.eventHandler(w, req) + if w.Code != http.StatusOK { + t.Errorf("POST commit_comment returned HTTP status code %v.\nExpected %v", w.Code, http.StatusOK) + } +} + +func TestMembershipEvent(t *testing.T) { + gh := NewGithubWebhooks() + jsonString := MembershipEventJSON() + req, _ := http.NewRequest("POST", "/", strings.NewReader(jsonString)) + req.Header.Add("X-Github-Event", "membership") + w := httptest.NewRecorder() + gh.eventHandler(w, req) + if w.Code != http.StatusOK { + t.Errorf("POST commit_comment returned HTTP status code %v.\nExpected %v", w.Code, http.StatusOK) + } +} + +func TestPageBuildEvent(t *testing.T) { + gh := NewGithubWebhooks() + jsonString := PageBuildEventJSON() + req, _ := http.NewRequest("POST", "/", strings.NewReader(jsonString)) + req.Header.Add("X-Github-Event", "page_build") + w := httptest.NewRecorder() + gh.eventHandler(w, req) + if w.Code != http.StatusOK { + t.Errorf("POST commit_comment returned HTTP status code %v.\nExpected %v", w.Code, http.StatusOK) + } +} + +func TestPublicEvent(t *testing.T) { + gh := NewGithubWebhooks() + jsonString := PublicEventJSON() + req, _ := http.NewRequest("POST", "/", strings.NewReader(jsonString)) + req.Header.Add("X-Github-Event", "public") + w := httptest.NewRecorder() + gh.eventHandler(w, req) + if w.Code != http.StatusOK { + t.Errorf("POST commit_comment returned HTTP status code %v.\nExpected %v", w.Code, http.StatusOK) + } +} + +func TestPullRequestReviewCommentEvent(t *testing.T) { + gh := NewGithubWebhooks() + jsonString := PullRequestReviewCommentEventJSON() + req, _ := http.NewRequest("POST", "/", strings.NewReader(jsonString)) + req.Header.Add("X-Github-Event", "pull_request_review_comment") + w := httptest.NewRecorder() + gh.eventHandler(w, req) + if w.Code != http.StatusOK { + t.Errorf("POST commit_comment returned HTTP status code %v.\nExpected %v", w.Code, http.StatusOK) + } +} + +func TestPushEvent(t *testing.T) { + gh := NewGithubWebhooks() + jsonString := PushEventJSON() + req, _ := http.NewRequest("POST", "/", strings.NewReader(jsonString)) + req.Header.Add("X-Github-Event", "push") + w := httptest.NewRecorder() + gh.eventHandler(w, req) + if w.Code != http.StatusOK { + t.Errorf("POST commit_comment returned HTTP status code %v.\nExpected %v", w.Code, http.StatusOK) + } +} + +func TestReleaseEvent(t *testing.T) { + gh := NewGithubWebhooks() + jsonString := ReleaseEventJSON() + req, _ := http.NewRequest("POST", "/", strings.NewReader(jsonString)) + req.Header.Add("X-Github-Event", "release") + w := httptest.NewRecorder() + gh.eventHandler(w, req) + if w.Code != http.StatusOK { + t.Errorf("POST commit_comment returned HTTP status code %v.\nExpected %v", w.Code, http.StatusOK) + } +} + +func TestRepositoryEvent(t *testing.T) { + gh := NewGithubWebhooks() + jsonString := RepositoryEventJSON() + req, _ := http.NewRequest("POST", "/", strings.NewReader(jsonString)) + req.Header.Add("X-Github-Event", "repository") + w := httptest.NewRecorder() + gh.eventHandler(w, req) + if w.Code != http.StatusOK { + t.Errorf("POST commit_comment returned HTTP status code %v.\nExpected %v", w.Code, http.StatusOK) + } +} + +func TestStatusEvent(t *testing.T) { + gh := NewGithubWebhooks() + + jsonString := StatusEventJSON() + req, _ := http.NewRequest("POST", "/", strings.NewReader(jsonString)) + req.Header.Add("X-Github-Event", "status") + w := httptest.NewRecorder() + gh.eventHandler(w, req) + if w.Code != http.StatusOK { + t.Errorf("POST commit_comment returned HTTP status code %v.\nExpected %v", w.Code, http.StatusOK) + } +} + +func TestTeamAddEvent(t *testing.T) { + gh := NewGithubWebhooks() + jsonString := TeamAddEventJSON() + req, _ := http.NewRequest("POST", "/", strings.NewReader(jsonString)) + req.Header.Add("X-Github-Event", "team_add") + w := httptest.NewRecorder() + gh.eventHandler(w, req) + if w.Code != http.StatusOK { + t.Errorf("POST commit_comment returned HTTP status code %v.\nExpected %v", w.Code, http.StatusOK) + } +} + +func TestWatchEvent(t *testing.T) { + gh := NewGithubWebhooks() + jsonString := WatchEventJSON() + req, _ := http.NewRequest("POST", "/", strings.NewReader(jsonString)) + req.Header.Add("X-Github-Event", "watch") + w := httptest.NewRecorder() + gh.eventHandler(w, req) + if w.Code != http.StatusOK { + t.Errorf("POST commit_comment returned HTTP status code %v.\nExpected %v", w.Code, http.StatusOK) + } +} diff --git a/plugins/inputs/httpjson/README.md b/plugins/inputs/httpjson/README.md index d016633a7..fc45dd567 100644 --- a/plugins/inputs/httpjson/README.md +++ b/plugins/inputs/httpjson/README.md @@ -45,6 +45,16 @@ You can also specify additional request parameters for the service: ``` +You can also specify additional request header parameters for the service: + +``` +[[httpjson.services]] + ... + + [httpjson.services.headers] + X-Auth-Token = "my-xauth-token" + apiVersion = "v1" +``` # Example: diff --git a/plugins/inputs/httpjson/httpjson.go b/plugins/inputs/httpjson/httpjson.go index b90a02e5b..bc4fe7899 100644 --- a/plugins/inputs/httpjson/httpjson.go +++ b/plugins/inputs/httpjson/httpjson.go @@ -21,6 +21,7 @@ type HttpJson struct { Method string TagKeys []string Parameters map[string]string + Headers map[string]string client HTTPClient } @@ -45,6 +46,9 @@ func (c RealHTTPClient) MakeRequest(req *http.Request) (*http.Response, error) { } var sampleConfig = ` + # NOTE This plugin only reads numerical measurements, strings and booleans + # will be ignored. + # a name for the service being polled name = "webserver_stats" @@ -67,6 +71,12 @@ var sampleConfig = ` [inputs.httpjson.parameters] event_type = "cpu_spike" threshold = "0.75" + + # HTTP Header parameters (all values must be strings) + # [inputs.httpjson.headers] + # X-Auth-Token = "my-xauth-token" + # apiVersion = "v1" + ` func (h *HttpJson) SampleConfig() string { @@ -188,6 +198,11 @@ func (h *HttpJson) sendRequest(serverURL string) (string, float64, error) { return "", -1, err } + // Add header parameters + for k, v := range h.Headers { + req.Header.Add(k, v) + } + start := time.Now() resp, err := h.client.MakeRequest(req) if err != nil { diff --git a/plugins/inputs/httpjson/httpjson_test.go b/plugins/inputs/httpjson/httpjson_test.go index 0ea5e9e42..9eff03887 100644 --- a/plugins/inputs/httpjson/httpjson_test.go +++ b/plugins/inputs/httpjson/httpjson_test.go @@ -97,6 +97,10 @@ func genMockHttpJson(response string, statusCode int) []*HttpJson { "httpParam1": "12", "httpParam2": "the second parameter", }, + Headers: map[string]string{ + "X-Auth-Token": "the-first-parameter", + "apiVersion": "v1", + }, }, &HttpJson{ client: mockHTTPClient{responseBody: response, statusCode: statusCode}, @@ -110,6 +114,10 @@ func genMockHttpJson(response string, statusCode int) []*HttpJson { "httpParam1": "12", "httpParam2": "the second parameter", }, + Headers: map[string]string{ + "X-Auth-Token": "the-first-parameter", + "apiVersion": "v1", + }, TagKeys: []string{ "role", "build", diff --git a/plugins/inputs/influxdb/influxdb.go b/plugins/inputs/influxdb/influxdb.go index e65c8afd2..311f6ba0c 100644 --- a/plugins/inputs/influxdb/influxdb.go +++ b/plugins/inputs/influxdb/influxdb.go @@ -130,7 +130,7 @@ func (i *InfluxDB) gatherURL( p.Tags["url"] = url acc.AddFields( - p.Name, + "influxdb_"+p.Name, p.Values, p.Tags, ) diff --git a/plugins/inputs/influxdb/influxdb_test.go b/plugins/inputs/influxdb/influxdb_test.go index e7b43e7bc..ef6c1a97a 100644 --- a/plugins/inputs/influxdb/influxdb_test.go +++ b/plugins/inputs/influxdb/influxdb_test.go @@ -84,7 +84,7 @@ func TestBasic(t *testing.T) { "id": "ex1", "url": fakeServer.URL + "/endpoint", } - acc.AssertContainsTaggedFields(t, "foo", fields, tags) + acc.AssertContainsTaggedFields(t, "influxdb_foo", fields, tags) fields = map[string]interface{}{ "x": "x", @@ -93,5 +93,5 @@ func TestBasic(t *testing.T) { "id": "ex2", "url": fakeServer.URL + "/endpoint", } - acc.AssertContainsTaggedFields(t, "bar", fields, tags) + acc.AssertContainsTaggedFields(t, "influxdb_bar", fields, tags) } diff --git a/plugins/inputs/procstat/procstat.go b/plugins/inputs/procstat/procstat.go index aa56bd501..fd8158ec7 100644 --- a/plugins/inputs/procstat/procstat.go +++ b/plugins/inputs/procstat/procstat.go @@ -129,9 +129,13 @@ func pidsFromFile(file string) ([]int32, error) { func pidsFromExe(exe string) ([]int32, error) { var out []int32 var outerr error - pgrep, err := exec.Command("pgrep", exe).Output() + bin, err := exec.LookPath("pgrep") if err != nil { - return out, fmt.Errorf("Failed to execute pgrep. Error: '%s'", err) + return out, fmt.Errorf("Couldn't find pgrep binary: %s", err) + } + pgrep, err := exec.Command(bin, exe).Output() + if err != nil { + return out, fmt.Errorf("Failed to execute %s. Error: '%s'", bin, err) } else { pids := strings.Fields(string(pgrep)) for _, pid := range pids { @@ -149,9 +153,13 @@ func pidsFromExe(exe string) ([]int32, error) { func pidsFromPattern(pattern string) ([]int32, error) { var out []int32 var outerr error - pgrep, err := exec.Command("pgrep", "-f", pattern).Output() + bin, err := exec.LookPath("pgrep") if err != nil { - return out, fmt.Errorf("Failed to execute pgrep. Error: '%s'", err) + return out, fmt.Errorf("Couldn't find pgrep binary: %s", err) + } + pgrep, err := exec.Command(bin, "-f", pattern).Output() + if err != nil { + return out, fmt.Errorf("Failed to execute %s. Error: '%s'", bin, err) } else { pids := strings.Fields(string(pgrep)) for _, pid := range pids { diff --git a/plugins/inputs/rabbitmq/rabbitmq.go b/plugins/inputs/rabbitmq/rabbitmq.go index c062b3164..103484e78 100644 --- a/plugins/inputs/rabbitmq/rabbitmq.go +++ b/plugins/inputs/rabbitmq/rabbitmq.go @@ -57,9 +57,14 @@ type ObjectTotals struct { } type QueueTotals struct { - Messages int64 - MessagesReady int64 `json:"messages_ready"` - MessagesUnacknowledged int64 `json:"messages_unacknowledged"` + Messages int64 + MessagesReady int64 `json:"messages_ready"` + MessagesUnacknowledged int64 `json:"messages_unacknowledged"` + MessageBytes int64 `json:"message_bytes"` + MessageBytesReady int64 `json:"message_bytes_ready"` + MessageBytesUnacknowledged int64 `json:"message_bytes_unacknowledged"` + MessageRam int64 `json:"message_bytes_ram"` + MessagePersistent int64 `json:"message_bytes_persistent"` } type Queue struct { @@ -270,6 +275,11 @@ func gatherQueues(r *RabbitMQ, acc inputs.Accumulator, errChan chan error) { "consumer_utilisation": queue.ConsumerUtilisation, "memory": queue.Memory, // messages information + "message_bytes": queue.MessageBytes, + "message_bytes_ready": queue.MessageBytesReady, + "message_bytes_unacked": queue.MessageBytesUnacknowledged, + "message_bytes_ram": queue.MessageRam, + "message_bytes_persist": queue.MessagePersistent, "messages": queue.Messages, "messages_ready": queue.MessagesReady, "messages_unack": queue.MessagesUnacknowledged, diff --git a/plugins/inputs/snmp/snmp.go b/plugins/inputs/snmp/snmp.go new file mode 100644 index 000000000..bebb54bdc --- /dev/null +++ b/plugins/inputs/snmp/snmp.go @@ -0,0 +1,473 @@ +package snmp + +import ( + "io/ioutil" + "log" + "net" + "regexp" + "strconv" + "strings" + "time" + + "github.com/influxdata/telegraf/plugins/inputs" + + "github.com/soniah/gosnmp" +) + +// Snmp is a snmp plugin +type Snmp struct { + Host []Host + Get []Data + Bulk []Data + SnmptranslateFile string +} + +type Host struct { + Address string + Community string + // SNMP version. Default 2 + Version int + // SNMP timeout, in seconds. 0 means no timeout + Timeout float64 + // SNMP retries + Retries int + // Data to collect (list of Data names) + Collect []string + // easy get oids + GetOids []string + // Oids + getOids []Data + bulkOids []Data +} + +type Data struct { + Name string + // OID (could be numbers or name) + Oid string + // Unit + Unit string + // SNMP getbulk max repetition + MaxRepetition uint8 `toml:"max_repetition"` + // SNMP Instance (default 0) + // (only used with GET request and if + // OID is a name from snmptranslate file) + Instance string + // OID (only number) (used for computation) + rawOid string +} + +type Node struct { + id string + name string + subnodes map[string]Node +} + +var initNode = Node{ + id: "1", + name: "", + subnodes: make(map[string]Node), +} + +var NameToOid = make(map[string]string) + +var sampleConfig = ` + # Use 'oids.txt' file to translate oids to names + # To generate 'oids.txt' you need to run: + # snmptranslate -m all -Tz -On | sed -e 's/"//g' > /tmp/oids.txt + # Or if you have an other MIB folder with custom MIBs + # snmptranslate -M /mycustommibfolder -Tz -On -m all | sed -e 's/"//g' > oids.txt + snmptranslate_file = "/tmp/oids.txt" + [[inputs.snmp.host]] + address = "192.168.2.2:161" + # SNMP community + community = "public" # default public + # SNMP version (1, 2 or 3) + # Version 3 not supported yet + version = 2 # default 2 + # SNMP response timeout + timeout = 2.0 # default 2.0 + # SNMP request retries + retries = 2 # default 2 + # Which get/bulk do you want to collect for this host + collect = ["mybulk", "sysservices", "sysdescr"] + # Simple list of OIDs to get, in addition to "collect" + get_oids = [] + + [[inputs.snmp.host]] + address = "192.168.2.3:161" + community = "public" + version = 2 + timeout = 2.0 + retries = 2 + collect = ["mybulk"] + get_oids = [ + "ifNumber", + ".1.3.6.1.2.1.1.3.0", + ] + + [[inputs.snmp.get]] + name = "ifnumber" + oid = "ifNumber" + + [[inputs.snmp.get]] + name = "interface_speed" + oid = "ifSpeed" + instance = 0 + + [[inputs.snmp.get]] + name = "sysuptime" + oid = ".1.3.6.1.2.1.1.3.0" + unit = "second" + + [[inputs.snmp.bulk]] + name = "mybulk" + max_repetition = 127 + oid = ".1.3.6.1.2.1.1" + + [[inputs.snmp.bulk]] + name = "ifoutoctets" + max_repetition = 127 + oid = "ifOutOctets" +` + +// SampleConfig returns sample configuration message +func (s *Snmp) SampleConfig() string { + return sampleConfig +} + +// Description returns description of Zookeeper plugin +func (s *Snmp) Description() string { + return `Reads oids value from one or many snmp agents` +} + +func fillnode(parentNode Node, oid_name string, ids []string) { + // ids = ["1", "3", "6", ...] + id, ids := ids[0], ids[1:] + node, ok := parentNode.subnodes[id] + if ok == false { + node = Node{ + id: id, + name: "", + subnodes: make(map[string]Node), + } + if len(ids) == 0 { + node.name = oid_name + } + parentNode.subnodes[id] = node + } + if len(ids) > 0 { + fillnode(node, oid_name, ids) + } +} + +func findnodename(node Node, ids []string) (string, string) { + // ids = ["1", "3", "6", ...] + if len(ids) == 1 { + return node.name, ids[0] + } + id, ids := ids[0], ids[1:] + // Get node + subnode, ok := node.subnodes[id] + if ok { + return findnodename(subnode, ids) + } + // We got a node + // Get node name + if node.name != "" && len(ids) == 0 && id == "0" { + // node with instance 0 + return node.name, "0" + } else if node.name != "" && len(ids) == 0 && id != "0" { + // node with an instance + return node.name, string(id) + } else if node.name != "" && len(ids) > 0 { + // node with subinstances + return node.name, strings.Join(ids, ".") + } + // return an empty node name + return node.name, "" +} + +func (s *Snmp) Gather(acc inputs.Accumulator) error { + // Create oid tree + if s.SnmptranslateFile != "" && len(initNode.subnodes) == 0 { + data, err := ioutil.ReadFile(s.SnmptranslateFile) + if err != nil { + log.Printf("Reading SNMPtranslate file error: %s", err) + return err + } else { + for _, line := range strings.Split(string(data), "\n") { + oidsRegEx := regexp.MustCompile(`([^\t]*)\t*([^\t]*)`) + oids := oidsRegEx.FindStringSubmatch(string(line)) + if oids[2] != "" { + oid_name := oids[1] + oid := oids[2] + fillnode(initNode, oid_name, strings.Split(string(oid), ".")) + NameToOid[oid_name] = oid + } + } + } + } + // Fetching data + for _, host := range s.Host { + // Set default args + if len(host.Address) == 0 { + host.Address = "127.0.0.1:161" + } + if host.Community == "" { + host.Community = "public" + } + if host.Timeout <= 0 { + host.Timeout = 2.0 + } + if host.Retries <= 0 { + host.Retries = 2 + } + // Prepare host + // Get Easy GET oids + for _, oidstring := range host.GetOids { + oid := Data{} + if val, ok := NameToOid[oidstring]; ok { + // TODO should we add the 0 instance ? + oid.Name = oidstring + oid.Oid = val + oid.rawOid = "." + val + ".0" + } else { + oid.Name = oidstring + oid.Oid = oidstring + if string(oidstring[:1]) != "." { + oid.rawOid = "." + oidstring + } else { + oid.rawOid = oidstring + } + } + host.getOids = append(host.getOids, oid) + } + + for _, oid_name := range host.Collect { + // Get GET oids + for _, oid := range s.Get { + if oid.Name == oid_name { + if val, ok := NameToOid[oid.Oid]; ok { + // TODO should we add the 0 instance ? + if oid.Instance != "" { + oid.rawOid = "." + val + "." + oid.Instance + } else { + oid.rawOid = "." + val + ".0" + } + } else { + oid.rawOid = oid.Oid + } + host.getOids = append(host.getOids, oid) + } + } + // Get GETBULK oids + for _, oid := range s.Bulk { + if oid.Name == oid_name { + if val, ok := NameToOid[oid.Oid]; ok { + oid.rawOid = "." + val + } else { + oid.rawOid = oid.Oid + } + host.bulkOids = append(host.bulkOids, oid) + } + } + } + // Launch Get requests + if err := host.SNMPGet(acc); err != nil { + return err + } + if err := host.SNMPBulk(acc); err != nil { + return err + } + } + return nil +} + +func (h *Host) SNMPGet(acc inputs.Accumulator) error { + // Get snmp client + snmpClient, err := h.GetSNMPClient() + if err != nil { + return err + } + // Deconnection + defer snmpClient.Conn.Close() + // Prepare OIDs + oidsList := make(map[string]Data) + for _, oid := range h.getOids { + oidsList[oid.rawOid] = oid + } + oidsNameList := make([]string, 0, len(oidsList)) + for _, oid := range oidsList { + oidsNameList = append(oidsNameList, oid.rawOid) + } + + // gosnmp.MAX_OIDS == 60 + // TODO use gosnmp.MAX_OIDS instead of hard coded value + max_oids := 60 + // limit 60 (MAX_OIDS) oids by requests + for i := 0; i < len(oidsList); i = i + max_oids { + // Launch request + max_index := i + max_oids + if i+max_oids > len(oidsList) { + max_index = len(oidsList) + } + result, err3 := snmpClient.Get(oidsNameList[i:max_index]) // Get() accepts up to g.MAX_OIDS + if err3 != nil { + return err3 + } + // Handle response + _, err = h.HandleResponse(oidsList, result, acc) + if err != nil { + return err + } + } + return nil +} + +func (h *Host) SNMPBulk(acc inputs.Accumulator) error { + // Get snmp client + snmpClient, err := h.GetSNMPClient() + if err != nil { + return err + } + // Deconnection + defer snmpClient.Conn.Close() + // Prepare OIDs + oidsList := make(map[string]Data) + for _, oid := range h.bulkOids { + oidsList[oid.rawOid] = oid + } + oidsNameList := make([]string, 0, len(oidsList)) + for _, oid := range oidsList { + oidsNameList = append(oidsNameList, oid.rawOid) + } + // TODO Trying to make requests with more than one OID + // to reduce the number of requests + for _, oid := range oidsNameList { + oid_asked := oid + need_more_requests := true + // Set max repetition + maxRepetition := oidsList[oid].MaxRepetition + if maxRepetition <= 0 { + maxRepetition = 32 + } + // Launch requests + for need_more_requests { + // Launch request + result, err3 := snmpClient.GetBulk([]string{oid}, 0, maxRepetition) + if err3 != nil { + return err3 + } + // Handle response + last_oid, err := h.HandleResponse(oidsList, result, acc) + if err != nil { + return err + } + // Determine if we need more requests + if strings.HasPrefix(last_oid, oid_asked) { + need_more_requests = true + oid = last_oid + } else { + need_more_requests = false + } + } + } + return nil +} + +func (h *Host) GetSNMPClient() (*gosnmp.GoSNMP, error) { + // Prepare Version + var version gosnmp.SnmpVersion + if h.Version == 1 { + version = gosnmp.Version1 + } else if h.Version == 3 { + version = gosnmp.Version3 + } else { + version = gosnmp.Version2c + } + // Prepare host and port + host, port_str, err := net.SplitHostPort(h.Address) + if err != nil { + port_str = string("161") + } + // convert port_str to port in uint16 + port_64, err := strconv.ParseUint(port_str, 10, 16) + port := uint16(port_64) + // Get SNMP client + snmpClient := &gosnmp.GoSNMP{ + Target: host, + Port: port, + Community: h.Community, + Version: version, + Timeout: time.Duration(h.Timeout) * time.Second, + Retries: h.Retries, + } + // Connection + err2 := snmpClient.Connect() + if err2 != nil { + return nil, err2 + } + // Return snmpClient + return snmpClient, nil +} + +func (h *Host) HandleResponse(oids map[string]Data, result *gosnmp.SnmpPacket, acc inputs.Accumulator) (string, error) { + var lastOid string + for _, variable := range result.Variables { + lastOid = variable.Name + // Remove unwanted oid + for oid_key, oid := range oids { + if strings.HasPrefix(variable.Name, oid_key) { + switch variable.Type { + // handle Metrics + case gosnmp.Boolean, gosnmp.Integer, gosnmp.Counter32, gosnmp.Gauge32, + gosnmp.TimeTicks, gosnmp.Counter64, gosnmp.Uinteger32: + // Prepare tags + tags := make(map[string]string) + if oid.Unit != "" { + tags["unit"] = oid.Unit + } + // Get name and instance + var oid_name string + var instance string + // Get oidname and instannce from translate file + oid_name, instance = findnodename(initNode, + strings.Split(string(variable.Name[1:]), ".")) + + if instance != "" { + tags["instance"] = instance + } + + // Set name + var field_name string + if oid_name != "" { + // Set fieldname as oid name from translate file + field_name = oid_name + } else { + // Set fieldname as oid name from inputs.snmp.get section + // Because the result oid is equal to inputs.snmp.get section + field_name = oid.Name + } + tags["host"], _, _ = net.SplitHostPort(h.Address) + fields := make(map[string]interface{}) + fields[string(field_name)] = variable.Value + + acc.AddFields(field_name, fields, tags) + case gosnmp.NoSuchObject, gosnmp.NoSuchInstance: + // Oid not found + log.Printf("[snmp input] Oid not found: %s", oid_key) + default: + // delete other data + } + break + } + } + } + return lastOid, nil +} + +func init() { + inputs.Add("snmp", func() inputs.Input { + return &Snmp{} + }) +} diff --git a/plugins/inputs/snmp/snmp_test.go b/plugins/inputs/snmp/snmp_test.go new file mode 100644 index 000000000..594a70217 --- /dev/null +++ b/plugins/inputs/snmp/snmp_test.go @@ -0,0 +1,459 @@ +package snmp + +import ( + "testing" + + "github.com/influxdata/telegraf/testutil" + + // "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestSNMPErrorGet1(t *testing.T) { + get1 := Data{ + Name: "oid1", + Unit: "octets", + Oid: ".1.3.6.1.2.1.2.2.1.16.1", + } + h := Host{ + Collect: []string{"oid1"}, + } + s := Snmp{ + SnmptranslateFile: "bad_oid.txt", + Host: []Host{h}, + Get: []Data{get1}, + } + + var acc testutil.Accumulator + err := s.Gather(&acc) + require.Error(t, err) +} + +func TestSNMPErrorGet2(t *testing.T) { + get1 := Data{ + Name: "oid1", + Unit: "octets", + Oid: ".1.3.6.1.2.1.2.2.1.16.1", + } + h := Host{ + Collect: []string{"oid1"}, + } + s := Snmp{ + Host: []Host{h}, + Get: []Data{get1}, + } + + var acc testutil.Accumulator + err := s.Gather(&acc) + require.Error(t, err) +} + +func TestSNMPErrorBulk(t *testing.T) { + bulk1 := Data{ + Name: "oid1", + Unit: "octets", + Oid: ".1.3.6.1.2.1.2.2.1.16", + } + h := Host{ + Address: "127.0.0.1", + Collect: []string{"oid1"}, + } + s := Snmp{ + Host: []Host{h}, + Bulk: []Data{bulk1}, + } + + var acc testutil.Accumulator + err := s.Gather(&acc) + require.Error(t, err) +} + +func TestSNMPGet1(t *testing.T) { + get1 := Data{ + Name: "oid1", + Unit: "octets", + Oid: ".1.3.6.1.2.1.2.2.1.16.1", + } + h := Host{ + Address: "127.0.0.1:31161", + Community: "telegraf", + Version: 2, + Timeout: 2.0, + Retries: 2, + Collect: []string{"oid1"}, + } + s := Snmp{ + Host: []Host{h}, + Get: []Data{get1}, + } + + var acc testutil.Accumulator + err := s.Gather(&acc) + require.NoError(t, err) + + acc.AssertContainsTaggedFields(t, + "oid1", + map[string]interface{}{ + "oid1": uint(543846), + }, + map[string]string{ + "unit": "octets", + "host": "127.0.0.1", + }, + ) +} + +func TestSNMPGet2(t *testing.T) { + get1 := Data{ + Name: "oid1", + Oid: "ifNumber", + } + h := Host{ + Address: "127.0.0.1:31161", + Community: "telegraf", + Version: 2, + Timeout: 2.0, + Retries: 2, + Collect: []string{"oid1"}, + } + s := Snmp{ + SnmptranslateFile: "./testdata/oids.txt", + Host: []Host{h}, + Get: []Data{get1}, + } + + var acc testutil.Accumulator + err := s.Gather(&acc) + require.NoError(t, err) + + acc.AssertContainsTaggedFields(t, + "ifNumber", + map[string]interface{}{ + "ifNumber": int(4), + }, + map[string]string{ + "instance": "0", + "host": "127.0.0.1", + }, + ) +} + +func TestSNMPGet3(t *testing.T) { + get1 := Data{ + Name: "oid1", + Unit: "octets", + Oid: "ifSpeed", + Instance: "1", + } + h := Host{ + Address: "127.0.0.1:31161", + Community: "telegraf", + Version: 2, + Timeout: 2.0, + Retries: 2, + Collect: []string{"oid1"}, + } + s := Snmp{ + SnmptranslateFile: "./testdata/oids.txt", + Host: []Host{h}, + Get: []Data{get1}, + } + + var acc testutil.Accumulator + err := s.Gather(&acc) + require.NoError(t, err) + + acc.AssertContainsTaggedFields(t, + "ifSpeed", + map[string]interface{}{ + "ifSpeed": uint(10000000), + }, + map[string]string{ + "unit": "octets", + "instance": "1", + "host": "127.0.0.1", + }, + ) +} + +func TestSNMPEasyGet4(t *testing.T) { + get1 := Data{ + Name: "oid1", + Unit: "octets", + Oid: "ifSpeed", + Instance: "1", + } + h := Host{ + Address: "127.0.0.1:31161", + Community: "telegraf", + Version: 2, + Timeout: 2.0, + Retries: 2, + Collect: []string{"oid1"}, + GetOids: []string{"ifNumber"}, + } + s := Snmp{ + SnmptranslateFile: "./testdata/oids.txt", + Host: []Host{h}, + Get: []Data{get1}, + } + + var acc testutil.Accumulator + err := s.Gather(&acc) + require.NoError(t, err) + + acc.AssertContainsTaggedFields(t, + "ifSpeed", + map[string]interface{}{ + "ifSpeed": uint(10000000), + }, + map[string]string{ + "unit": "octets", + "instance": "1", + "host": "127.0.0.1", + }, + ) + + acc.AssertContainsTaggedFields(t, + "ifNumber", + map[string]interface{}{ + "ifNumber": int(4), + }, + map[string]string{ + "instance": "0", + "host": "127.0.0.1", + }, + ) +} + +func TestSNMPEasyGet5(t *testing.T) { + get1 := Data{ + Name: "oid1", + Unit: "octets", + Oid: "ifSpeed", + Instance: "1", + } + h := Host{ + Address: "127.0.0.1:31161", + Community: "telegraf", + Version: 2, + Timeout: 2.0, + Retries: 2, + Collect: []string{"oid1"}, + GetOids: []string{".1.3.6.1.2.1.2.1.0"}, + } + s := Snmp{ + SnmptranslateFile: "./testdata/oids.txt", + Host: []Host{h}, + Get: []Data{get1}, + } + + var acc testutil.Accumulator + err := s.Gather(&acc) + require.NoError(t, err) + + acc.AssertContainsTaggedFields(t, + "ifSpeed", + map[string]interface{}{ + "ifSpeed": uint(10000000), + }, + map[string]string{ + "unit": "octets", + "instance": "1", + "host": "127.0.0.1", + }, + ) + + acc.AssertContainsTaggedFields(t, + "ifNumber", + map[string]interface{}{ + "ifNumber": int(4), + }, + map[string]string{ + "instance": "0", + "host": "127.0.0.1", + }, + ) +} + +func TestSNMPEasyGet6(t *testing.T) { + h := Host{ + Address: "127.0.0.1:31161", + Community: "telegraf", + Version: 2, + Timeout: 2.0, + Retries: 2, + GetOids: []string{"1.3.6.1.2.1.2.1.0"}, + } + s := Snmp{ + SnmptranslateFile: "./testdata/oids.txt", + Host: []Host{h}, + } + + var acc testutil.Accumulator + err := s.Gather(&acc) + require.NoError(t, err) + + acc.AssertContainsTaggedFields(t, + "ifNumber", + map[string]interface{}{ + "ifNumber": int(4), + }, + map[string]string{ + "instance": "0", + "host": "127.0.0.1", + }, + ) +} + +func TestSNMPBulk1(t *testing.T) { + bulk1 := Data{ + Name: "oid1", + Unit: "octets", + Oid: ".1.3.6.1.2.1.2.2.1.16", + MaxRepetition: 2, + } + h := Host{ + Address: "127.0.0.1:31161", + Community: "telegraf", + Version: 2, + Timeout: 2.0, + Retries: 2, + Collect: []string{"oid1"}, + } + s := Snmp{ + SnmptranslateFile: "./testdata/oids.txt", + Host: []Host{h}, + Bulk: []Data{bulk1}, + } + + var acc testutil.Accumulator + err := s.Gather(&acc) + require.NoError(t, err) + + acc.AssertContainsTaggedFields(t, + "ifOutOctets", + map[string]interface{}{ + "ifOutOctets": uint(543846), + }, + map[string]string{ + "unit": "octets", + "instance": "1", + "host": "127.0.0.1", + }, + ) + + acc.AssertContainsTaggedFields(t, + "ifOutOctets", + map[string]interface{}{ + "ifOutOctets": uint(26475179), + }, + map[string]string{ + "unit": "octets", + "instance": "2", + "host": "127.0.0.1", + }, + ) + + acc.AssertContainsTaggedFields(t, + "ifOutOctets", + map[string]interface{}{ + "ifOutOctets": uint(108963968), + }, + map[string]string{ + "unit": "octets", + "instance": "3", + "host": "127.0.0.1", + }, + ) + + acc.AssertContainsTaggedFields(t, + "ifOutOctets", + map[string]interface{}{ + "ifOutOctets": uint(12991453), + }, + map[string]string{ + "unit": "octets", + "instance": "36", + "host": "127.0.0.1", + }, + ) +} + +// TODO find why, if this test is active +// Circle CI stops with the following error... +// bash scripts/circle-test.sh died unexpectedly +// Maybe the test is too long ?? +func dTestSNMPBulk2(t *testing.T) { + bulk1 := Data{ + Name: "oid1", + Unit: "octets", + Oid: "ifOutOctets", + MaxRepetition: 2, + } + h := Host{ + Address: "127.0.0.1:31161", + Community: "telegraf", + Version: 2, + Timeout: 2.0, + Retries: 2, + Collect: []string{"oid1"}, + } + s := Snmp{ + SnmptranslateFile: "./testdata/oids.txt", + Host: []Host{h}, + Bulk: []Data{bulk1}, + } + + var acc testutil.Accumulator + err := s.Gather(&acc) + require.NoError(t, err) + + acc.AssertContainsTaggedFields(t, + "ifOutOctets", + map[string]interface{}{ + "ifOutOctets": uint(543846), + }, + map[string]string{ + "unit": "octets", + "instance": "1", + "host": "127.0.0.1", + }, + ) + + acc.AssertContainsTaggedFields(t, + "ifOutOctets", + map[string]interface{}{ + "ifOutOctets": uint(26475179), + }, + map[string]string{ + "unit": "octets", + "instance": "2", + "host": "127.0.0.1", + }, + ) + + acc.AssertContainsTaggedFields(t, + "ifOutOctets", + map[string]interface{}{ + "ifOutOctets": uint(108963968), + }, + map[string]string{ + "unit": "octets", + "instance": "3", + "host": "127.0.0.1", + }, + ) + + acc.AssertContainsTaggedFields(t, + "ifOutOctets", + map[string]interface{}{ + "ifOutOctets": uint(12991453), + }, + map[string]string{ + "unit": "octets", + "instance": "36", + "host": "127.0.0.1", + }, + ) +} diff --git a/plugins/inputs/snmp/testdata/oids.txt b/plugins/inputs/snmp/testdata/oids.txt new file mode 100644 index 000000000..1a351be90 --- /dev/null +++ b/plugins/inputs/snmp/testdata/oids.txt @@ -0,0 +1,32 @@ +org 1.3 +dod 1.3.6 +internet 1.3.6.1 +directory 1.3.6.1.1 +mgmt 1.3.6.1.2 +mib-2 1.3.6.1.2.1 +interfaces 1.3.6.1.2.1.2 +ifNumber 1.3.6.1.2.1.2.1 +ifTable 1.3.6.1.2.1.2.2 +ifEntry 1.3.6.1.2.1.2.2.1 +ifIndex 1.3.6.1.2.1.2.2.1.1 +ifDescr 1.3.6.1.2.1.2.2.1.2 +ifType 1.3.6.1.2.1.2.2.1.3 +ifMtu 1.3.6.1.2.1.2.2.1.4 +ifSpeed 1.3.6.1.2.1.2.2.1.5 +ifPhysAddress 1.3.6.1.2.1.2.2.1.6 +ifAdminStatus 1.3.6.1.2.1.2.2.1.7 +ifOperStatus 1.3.6.1.2.1.2.2.1.8 +ifLastChange 1.3.6.1.2.1.2.2.1.9 +ifInOctets 1.3.6.1.2.1.2.2.1.10 +ifInUcastPkts 1.3.6.1.2.1.2.2.1.11 +ifInNUcastPkts 1.3.6.1.2.1.2.2.1.12 +ifInDiscards 1.3.6.1.2.1.2.2.1.13 +ifInErrors 1.3.6.1.2.1.2.2.1.14 +ifInUnknownProtos 1.3.6.1.2.1.2.2.1.15 +ifOutOctets 1.3.6.1.2.1.2.2.1.16 +ifOutUcastPkts 1.3.6.1.2.1.2.2.1.17 +ifOutNUcastPkts 1.3.6.1.2.1.2.2.1.18 +ifOutDiscards 1.3.6.1.2.1.2.2.1.19 +ifOutErrors 1.3.6.1.2.1.2.2.1.20 +ifOutQLen 1.3.6.1.2.1.2.2.1.21 +ifSpecific 1.3.6.1.2.1.2.2.1.22 diff --git a/plugins/inputs/sqlserver/README.md b/plugins/inputs/sqlserver/README.md new file mode 100644 index 000000000..e67530175 --- /dev/null +++ b/plugins/inputs/sqlserver/README.md @@ -0,0 +1,50 @@ +# SQL Server plugin + +This sqlserver plugin provides metrics for your SQL Server instance. +It currently works with SQL Server versions 2008+. +Recorded metrics are lightweight and use Dynamic Management Views supplied by SQL Server: +``` +Performance counters : 1000+ metrics from sys.dm_os_performance_counters +Performance metrics : special performance and ratio metrics +Wait stats : wait tasks categorized from sys.dm_os_wait_stats +Memory clerk : memory breakdown from sys.dm_os_memory_clerks +Database size : databases size trend from sys.dm_io_virtual_file_stats +Database IO : databases I/O from sys.dm_io_virtual_file_stats +Database latency : databases latency from sys.dm_io_virtual_file_stats +Database properties : databases properties, state and recovery model, from sys.databases +OS Volume : available, used and total space from sys.dm_os_volume_stats +CPU : cpu usage from sys.dm_os_ring_buffers +``` + +You must create a login on every instance you want to monitor, with following script: +```SQL +USE master; +GO +CREATE LOGIN [telegraf] WITH PASSWORD = N'mystrongpassword'; +GO +GRANT VIEW SERVER STATE TO [telegraf]; +GO +GRANT VIEW ANY DEFINITION TO [telegraf]; +GO +``` + +Overview +![telegraf-sqlserver-0](https://cloud.githubusercontent.com/assets/16494280/12538189/ec1b70aa-c2d3-11e5-97ec-1a4f575e8a07.png) + +General Activity +![telegraf-sqlserver-1](https://cloud.githubusercontent.com/assets/16494280/12591410/f098b602-c467-11e5-9acf-2edea077ed7e.png) + +Memory +![telegraf-sqlserver-2](https://cloud.githubusercontent.com/assets/16494280/12591412/f2075688-c467-11e5-9d0f-d256e032cd0e.png) + +I/O +![telegraf-sqlserver-3](https://cloud.githubusercontent.com/assets/16494280/12591417/f40ccb84-c467-11e5-89ff-498fb1bc3110.png) + +Disks +![telegraf-sqlserver-4](https://cloud.githubusercontent.com/assets/16494280/12591420/f5de5f68-c467-11e5-90c8-9185444ac490.png) + +CPU +![telegraf-sqlserver-5](https://cloud.githubusercontent.com/assets/16494280/12591446/11dfe7b8-c468-11e5-9681-6e33296e70e8.png) + +Full view +![telegraf-sqlserver-full](https://cloud.githubusercontent.com/assets/16494280/12591426/fa2b17b4-c467-11e5-9c00-929f4c4aea57.png) diff --git a/plugins/inputs/sqlserver/sqlserver.go b/plugins/inputs/sqlserver/sqlserver.go new file mode 100644 index 000000000..4c6214822 --- /dev/null +++ b/plugins/inputs/sqlserver/sqlserver.go @@ -0,0 +1,1510 @@ +package sqlserver + +import ( + "database/sql" + "github.com/influxdata/telegraf/plugins/inputs" + "sync" + "time" + + // go-mssqldb initialization + _ "github.com/zensqlmonitor/go-mssqldb" +) + +// SQLServer struct +type SQLServer struct { + Servers []string +} + +// Query struct +type Query struct { + Script string + ResultByRow bool + OrderedColumns []string +} + +// MapQuery type +type MapQuery map[string]Query + +var queries MapQuery + +var defaultServer = "Server=.;app name=telegraf;log=1;" + +var sampleConfig = ` + # Specify instances to monitor with a list of connection strings. + # All connection parameters are optional. + # By default, the host is localhost, listening on default port, TCP 1433. + # for Windows, the user is the currently running AD user (SSO). + # See https://github.com/denisenkom/go-mssqldb for detailed connection parameters. + + # servers = [ + # "Server=192.168.1.10;Port=1433;User Id=telegraf;Password=T$l$gr@f69*;app name=telegraf;log=1;", + # ] +` + +// SampleConfig return the sample configuration +func (s *SQLServer) SampleConfig() string { + return sampleConfig +} + +// Description return plugin description +func (s *SQLServer) Description() string { + return "Read metrics from Microsoft SQL Server" +} + +type scanner interface { + Scan(dest ...interface{}) error +} + +func initQueries() { + queries = make(MapQuery) + queries["PerformanceCounters"] = Query{Script: sqlPerformanceCounters, ResultByRow: true} + queries["WaitStatsCategorized"] = Query{Script: sqlWaitStatsCategorized, ResultByRow: false} + queries["CPUHistory"] = Query{Script: sqlCPUHistory, ResultByRow: false} + queries["DatabaseIO"] = Query{Script: sqlDatabaseIO, ResultByRow: false} + queries["DatabaseSize"] = Query{Script: sqlDatabaseSize, ResultByRow: false} + queries["DatabaseStats"] = Query{Script: sqlDatabaseStats, ResultByRow: false} + queries["DatabaseProperties"] = Query{Script: sqlDatabaseProperties, ResultByRow: false} + queries["MemoryClerk"] = Query{Script: sqlMemoryClerk, ResultByRow: false} + queries["VolumeSpace"] = Query{Script: sqlVolumeSpace, ResultByRow: false} + queries["PerformanceMetrics"] = Query{Script: sqlPerformanceMetrics, ResultByRow: false} +} + +// Gather collect data from SQL Server +func (s *SQLServer) Gather(acc inputs.Accumulator) error { + initQueries() + + if len(s.Servers) == 0 { + s.Servers = append(s.Servers, defaultServer) + } + + var wg sync.WaitGroup + var outerr error + + for _, serv := range s.Servers { + for _, query := range queries { + wg.Add(1) + go func(serv string, query Query) { + defer wg.Done() + outerr = s.gatherServer(serv, query, acc) + }(serv, query) + } + } + + wg.Wait() + return outerr +} + +func (s *SQLServer) gatherServer(server string, query Query, acc inputs.Accumulator) error { + // deferred opening + conn, err := sql.Open("mssql", server) + if err != nil { + return err + } + // verify that a connection can be made before making a query + err = conn.Ping() + if err != nil { + // Handle error + return err + } + defer conn.Close() + + // execute query + rows, err := conn.Query(query.Script) + if err != nil { + return err + } + defer rows.Close() + + // grab the column information from the result + query.OrderedColumns, err = rows.Columns() + if err != nil { + return err + } + + for rows.Next() { + err = s.accRow(query, acc, rows) + if err != nil { + return err + } + } + return rows.Err() +} + +func (s *SQLServer) accRow(query Query, acc inputs.Accumulator, row scanner) error { + var columnVars []interface{} + var fields = make(map[string]interface{}) + + // store the column name with its *interface{} + columnMap := make(map[string]*interface{}) + for _, column := range query.OrderedColumns { + columnMap[column] = new(interface{}) + } + // populate the array of interface{} with the pointers in the right order + for i := 0; i < len(columnMap); i++ { + columnVars = append(columnVars, columnMap[query.OrderedColumns[i]]) + } + // deconstruct array of variables and send to Scan + err := row.Scan(columnVars...) + if err != nil { + return err + } + + // measurement: identified by the header + // tags: all other fields of type string + tags := map[string]string{} + var measurement string + for header, val := range columnMap { + if str, ok := (*val).(string); ok { + if header == "measurement" { + measurement = str + } else { + tags[header] = str + } + } + } + + if query.ResultByRow { + // add measurement to Accumulator + acc.Add(measurement, *columnMap["value"], tags, time.Now()) + } else { + // values + for header, val := range columnMap { + if _, ok := (*val).(string); !ok { + fields[header] = (*val) + } + } + // add fields to Accumulator + acc.AddFields(measurement, fields, tags, time.Now()) + } + return nil +} + +func init() { + inputs.Add("sqlserver", func() inputs.Input { + return &SQLServer{} + }) +} + +// queries +const sqlPerformanceMetrics string = `SET NOCOUNT ON; +SET ARITHABORT ON; +SET QUOTED_IDENTIFIER ON; +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED + +DECLARE @PCounters TABLE +( + counter_name nvarchar(64), + cntr_value bigint, + Primary Key(counter_name) +); + +INSERT @PCounters (counter_name, cntr_value) +SELECT 'Point In Time Recovery', Value = CASE + WHEN 1 > 1.0 * COUNT(*) / NULLIF((SELECT COUNT(*) FROM sys.databases d WHERE database_id > 4), 0) + THEN 0 ELSE 1 END +FROM sys.databases d +WHERE database_id > 4 + AND recovery_model IN (1) +UNION ALL +SELECT 'Page File Usage (%)', CAST(100 * (1 - available_page_file_kb * 1. / total_page_file_kb) as decimal(9,2)) as [PageFileUsage (%)] +FROM sys.dm_os_sys_memory +UNION ALL +SELECT 'Connection memory per connection (bytes)', Ratio = CAST((cntr_value / (SELECT 1.0 * cntr_value FROM sys.dm_os_performance_counters WHERE counter_name = 'User Connections')) * 1024 as int) +FROM sys.dm_os_performance_counters +WHERE counter_name = 'Connection Memory (KB)' +UNION ALL +SELECT 'Available physical memory (bytes)', available_physical_memory_kb * 1024 +FROM sys.dm_os_sys_memory +UNION ALL +SELECT 'Signal wait (%)', SignalWaitPercent = CAST(100.0 * SUM(signal_wait_time_ms) / SUM (wait_time_ms) AS NUMERIC(20,2)) +FROM sys.dm_os_wait_stats +UNION ALL +SELECT 'Sql compilation per batch request', SqlCompilationPercent = 100.0 * cntr_value / (SELECT 1.0*cntr_value FROM sys.dm_os_performance_counters WHERE counter_name = 'Batch Requests/sec') +FROM sys.dm_os_performance_counters +WHERE counter_name = 'SQL Compilations/sec' +UNION ALL +SELECT 'Sql recompilation per batch request', SqlReCompilationPercent = 100.0 *cntr_value / (SELECT 1.0*cntr_value FROM sys.dm_os_performance_counters WHERE counter_name = 'Batch Requests/sec') +FROM sys.dm_os_performance_counters +WHERE counter_name = 'SQL Re-Compilations/sec' +UNION ALL +SELECT 'Page lookup per batch request',PageLookupPercent = 100.0 * cntr_value / (SELECT 1.0*cntr_value FROM sys.dm_os_performance_counters WHERE counter_name = 'Batch Requests/sec') +FROM sys.dm_os_performance_counters +WHERE counter_name = 'Page lookups/sec' +UNION ALL +SELECT 'Page split per batch request',PageSplitPercent = 100.0 * cntr_value / (SELECT 1.0*cntr_value FROM sys.dm_os_performance_counters WHERE counter_name = 'Batch Requests/sec') +FROM sys.dm_os_performance_counters +WHERE counter_name = 'Page splits/sec' +UNION ALL +SELECT 'Average tasks', AverageTaskCount = (SELECT AVG(current_tasks_count) FROM sys.dm_os_schedulers WITH (NOLOCK) WHERE scheduler_id < 255 ) +UNION ALL +SELECT 'Average runnable tasks', AverageRunnableTaskCount = (SELECT AVG(runnable_tasks_count) FROM sys.dm_os_schedulers WITH (NOLOCK) WHERE scheduler_id < 255 ) +UNION ALL +SELECT 'Average pending disk IO', AveragePendingDiskIOCount = (SELECT AVG(pending_disk_io_count) FROM sys.dm_os_schedulers WITH (NOLOCK) WHERE scheduler_id < 255 ) +UNION ALL +SELECT 'Buffer pool rate (bytes/sec)', BufferPoolRate = (1.0*cntr_value * 8 * 1024) / + (SELECT 1.0*cntr_value FROM sys.dm_os_performance_counters WHERE object_name like '%Buffer Manager%' AND lower(counter_name) = 'Page life expectancy') +FROM sys.dm_os_performance_counters +WHERE object_name like '%Buffer Manager%' +AND counter_name = 'database pages' +UNION ALL +SELECT 'Memory grant pending', MemoryGrantPending = cntr_value +FROM sys.dm_os_performance_counters +WHERE counter_name = 'Memory Grants Pending' +UNION ALL +SELECT 'Readahead per page read', Readahead = 100.0 *cntr_value / (SELECT 1.0*cntr_value FROM sys.dm_os_performance_counters WHERE counter_name = 'Page Reads/sec') +FROM sys.dm_os_performance_counters +WHERE counter_name = 'Readahead pages/sec' +UNION ALL +SELECT 'Total target memory ratio', TotalTargetMemoryRatio = 100.0 * cntr_value / (SELECT 1.0*cntr_value FROM sys.dm_os_performance_counters WHERE counter_name = 'Target Server Memory (KB)') +FROM sys.dm_os_performance_counters +WHERE counter_name = 'Total Server Memory (KB)' + +IF OBJECT_ID('tempdb..#PCounters') IS NOT NULL DROP TABLE #PCounters; +SELECT * INTO #PCounters FROM @PCounters + +DECLARE @DynamicPivotQuery AS NVARCHAR(MAX) +DECLARE @ColumnName AS NVARCHAR(MAX) +SELECT @ColumnName= ISNULL(@ColumnName + ',','') + QUOTENAME(counter_name) +FROM (SELECT DISTINCT counter_name FROM @PCounters) AS bl + +SET @DynamicPivotQuery = N' +SELECT measurement = ''Performance metrics'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''Performance metrics'' +, ' + @ColumnName + ' FROM +( +SELECT counter_name, cntr_value +FROM #PCounters +) as V +PIVOT(SUM(cntr_value) FOR counter_name IN (' + @ColumnName + ')) AS PVTTable +' +EXEC sp_executesql @DynamicPivotQuery; +` + +const sqlMemoryClerk string = `SET NOCOUNT ON; +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; + +DECLARE @w TABLE (ClerkCategory nvarchar(64) NOT NULL, UsedPercent decimal(9,2), UsedBytes bigint) +INSERT @w (ClerkCategory, UsedPercent, UsedBytes) +SELECT ClerkCategory +, UsedPercent = SUM(UsedPercent) +, UsedBytes = SUM(UsedBytes) +FROM +( +SELECT ClerkCategory = CASE MC.[type] + WHEN 'MEMORYCLERK_SQLBUFFERPOOL' THEN 'Buffer pool' + WHEN 'CACHESTORE_SQLCP' THEN 'Cache (sql plans)' + WHEN 'CACHESTORE_OBJCP' THEN 'Cache (objects)' + ELSE 'Other' END +, SUM(pages_kb * 1024) AS UsedBytes +, Cast(100 * Sum(pages_kb)*1.0/(Select Sum(pages_kb) From sys.dm_os_memory_clerks) as Decimal(7, 4)) UsedPercent +FROM sys.dm_os_memory_clerks MC +WHERE pages_kb > 0 +GROUP BY CASE MC.[type] + WHEN 'MEMORYCLERK_SQLBUFFERPOOL' THEN 'Buffer pool' + WHEN 'CACHESTORE_SQLCP' THEN 'Cache (sql plans)' + WHEN 'CACHESTORE_OBJCP' THEN 'Cache (objects)' + ELSE 'Other' END +) as T +GROUP BY ClerkCategory + +SELECT +-- measurement +measurement +-- tags +, servername= REPLACE(@@SERVERNAME, '\', ':') +, type = 'Memory clerk' +-- value +, [Buffer pool] +, [Cache (objects)] +, [Cache (sql plans)] +, [Other] +FROM +( +SELECT measurement = 'Memory breakdown (%)' +, [Buffer pool] = ISNULL(ROUND([Buffer Pool], 1), 0) +, [Cache (objects)] = ISNULL(ROUND([Cache (objects)], 1), 0) +, [Cache (sql plans)] = ISNULL(ROUND([Cache (sql plans)], 1), 0) +, [Other] = ISNULL(ROUND([Other], 1), 0) +FROM (SELECT ClerkCategory, UsedPercent FROM @w) as G1 +PIVOT +( + SUM(UsedPercent) + FOR ClerkCategory IN ([Buffer Pool], [Cache (objects)], [Cache (sql plans)], [Other]) +) AS PivotTable + +UNION ALL + +SELECT measurement = 'Memory breakdown (bytes)' +, [Buffer pool] = ISNULL(ROUND([Buffer Pool], 1), 0) +, [Cache (objects)] = ISNULL(ROUND([Cache (objects)], 1), 0) +, [Cache (sql plans)] = ISNULL(ROUND([Cache (sql plans)], 1), 0) +, [Other] = ISNULL(ROUND([Other], 1), 0) +FROM (SELECT ClerkCategory, UsedBytes FROM @w) as G2 +PIVOT +( + SUM(UsedBytes) + FOR ClerkCategory IN ([Buffer Pool], [Cache (objects)], [Cache (sql plans)], [Other]) +) AS PivotTable +) as T; +` + +const sqlDatabaseSize string = `SET NOCOUNT ON; +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED + +IF OBJECT_ID('tempdb..#baseline') IS NOT NULL + DROP TABLE #baseline; +SELECT + DB_NAME(mf.database_id) AS database_name , + size_on_disk_bytes , + type_desc as datafile_type, + GETDATE() AS baselineDate +INTO #baseline +FROM sys.dm_io_virtual_file_stats(NULL, NULL) AS divfs +INNER JOIN sys.master_files AS mf ON mf.database_id = divfs.database_id + AND mf.file_id = divfs.file_id + +DECLARE @DynamicPivotQuery AS NVARCHAR(MAX) +DECLARE @ColumnName AS NVARCHAR(MAX), @ColumnName2 AS NVARCHAR(MAX) + +SELECT @ColumnName= ISNULL(@ColumnName + ',','') + QUOTENAME(database_name) +FROM (SELECT DISTINCT database_name FROM #baseline) AS bl + +--Prepare the PIVOT query using the dynamic +SET @DynamicPivotQuery = N' +SELECT measurement = ''Log size (bytes)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''Database size'' +, ' + @ColumnName + ' FROM +( +SELECT database_name, size_on_disk_bytes +FROM #baseline +WHERE datafile_type = ''LOG'' +) as V +PIVOT(SUM(size_on_disk_bytes) FOR database_name IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = ''Rows size (bytes)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''Database size'' +, ' + @ColumnName + ' FROM +( +SELECT database_name, size_on_disk_bytes +FROM #baseline +WHERE datafile_type = ''ROWS'' +) as V +PIVOT(SUM(size_on_disk_bytes) FOR database_name IN (' + @ColumnName + ')) AS PVTTable +' +--PRINT @DynamicPivotQuery +EXEC sp_executesql @DynamicPivotQuery; +` + +const sqlDatabaseStats string = `SET NOCOUNT ON; +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; + +IF OBJECT_ID('tempdb..#baseline') IS NOT NULL + DROP TABLE #baseline; + +SELECT +[ReadLatency] = + CASE WHEN [num_of_reads] = 0 + THEN 0 ELSE ([io_stall_read_ms] / [num_of_reads]) END, +[WriteLatency] = + CASE WHEN [num_of_writes] = 0 + THEN 0 ELSE ([io_stall_write_ms] / [num_of_writes]) END, +[Latency] = + CASE WHEN ([num_of_reads] = 0 AND [num_of_writes] = 0) + THEN 0 ELSE ([io_stall] / ([num_of_reads] + [num_of_writes])) END, +[AvgBytesPerRead] = + CASE WHEN [num_of_reads] = 0 + THEN 0 ELSE ([num_of_bytes_read] / [num_of_reads]) END, +[AvgBytesPerWrite] = + CASE WHEN [num_of_writes] = 0 + THEN 0 ELSE ([num_of_bytes_written] / [num_of_writes]) END, +[AvgBytesPerTransfer] = + CASE WHEN ([num_of_reads] = 0 AND [num_of_writes] = 0) + THEN 0 ELSE + (([num_of_bytes_read] + [num_of_bytes_written]) / + ([num_of_reads] + [num_of_writes])) END, +DB_NAME ([vfs].[database_id]) AS DatabaseName, +[mf].type_desc as datafile_type +INTO #baseline +FROM sys.dm_io_virtual_file_stats (NULL,NULL) AS [vfs] +JOIN sys.master_files AS [mf] ON [vfs].[database_id] = [mf].[database_id] + AND [vfs].[file_id] = [mf].[file_id] + + + +DECLARE @DynamicPivotQuery AS NVARCHAR(MAX) +DECLARE @ColumnName AS NVARCHAR(MAX), @ColumnName2 AS NVARCHAR(MAX) + +SELECT @ColumnName= ISNULL(@ColumnName + ',','') + QUOTENAME(DatabaseName) +FROM (SELECT DISTINCT DatabaseName FROM #baseline) AS bl + +--Prepare the PIVOT query using the dynamic +SET @DynamicPivotQuery = N' +SELECT measurement = ''Log read latency (ms)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''Database stats'' +, ' + @ColumnName + ' FROM +( +SELECT DatabaseName, ReadLatency +FROM #baseline +WHERE datafile_type = ''LOG'' +) as V +PIVOT(SUM(ReadLatency) FOR DatabaseName IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = ''Log write latency (ms)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''Database stats'' +, ' + @ColumnName + ' FROM +( +SELECT DatabaseName, WriteLatency +FROM #baseline +WHERE datafile_type = ''LOG'' +) as V +PIVOT(SUM(WriteLatency) FOR DatabaseName IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = ''Rows read latency (ms)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''Database stats'' +, ' + @ColumnName + ' FROM +( +SELECT DatabaseName, ReadLatency +FROM #baseline +WHERE datafile_type = ''ROWS'' +) as V +PIVOT(SUM(ReadLatency) FOR DatabaseName IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = ''Rows write latency (ms)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''Database stats'' +, ' + @ColumnName + ' FROM +( +SELECT DatabaseName, WriteLatency +FROM #baseline +WHERE datafile_type = ''ROWS'' +) as V +PIVOT(SUM(WriteLatency) FOR DatabaseName IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = ''Rows (average bytes/read)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''Database stats'' +, ' + @ColumnName + ' FROM +( +SELECT DatabaseName, AvgBytesPerRead +FROM #baseline +WHERE datafile_type = ''ROWS'' +) as V +PIVOT(SUM(AvgBytesPerRead) FOR DatabaseName IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = ''Rows (average bytes/write)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''Database stats'' +, ' + @ColumnName + ' FROM +( +SELECT DatabaseName, AvgBytesPerWrite +FROM #baseline +WHERE datafile_type = ''ROWS'' +) as V +PIVOT(SUM(AvgBytesPerWrite) FOR DatabaseName IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = ''Log (average bytes/read)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''Database stats'' +, ' + @ColumnName + ' FROM +( +SELECT DatabaseName, AvgBytesPerRead +FROM #baseline +WHERE datafile_type = ''LOG'' +) as V +PIVOT(SUM(AvgBytesPerRead) FOR DatabaseName IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = ''Log (average bytes/write)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''Database stats'' +, ' + @ColumnName + ' FROM +( +SELECT DatabaseName, AvgBytesPerWrite +FROM #baseline +WHERE datafile_type = ''LOG'' +) as V +PIVOT(SUM(AvgBytesPerWrite) FOR DatabaseName IN (' + @ColumnName + ')) AS PVTTable +' +--PRINT @DynamicPivotQuery +EXEC sp_executesql @DynamicPivotQuery; +` + +const sqlDatabaseIO string = `SET NOCOUNT ON; +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +DECLARE @secondsBetween tinyint = 5; +DECLARE @delayInterval char(8) = CONVERT(Char(8), DATEADD(SECOND, @secondsBetween, '00:00:00'), 108); + +IF OBJECT_ID('tempdb..#baseline') IS NOT NULL + DROP TABLE #baseline; +IF OBJECT_ID('tempdb..#baselinewritten') IS NOT NULL + DROP TABLE #baselinewritten; + +SELECT DB_NAME(mf.database_id) AS databaseName , + mf.physical_name, + divfs.num_of_bytes_read, + divfs.num_of_bytes_written, + divfs.num_of_reads, + divfs.num_of_writes, + GETDATE() AS baselineDate +INTO #baseline +FROM sys.dm_io_virtual_file_stats(NULL, NULL) AS divfs +INNER JOIN sys.master_files AS mf ON mf.database_id = divfs.database_id + AND mf.file_id = divfs.file_id + +WAITFOR DELAY @delayInterval; + +;WITH currentLine AS +( + SELECT DB_NAME(mf.database_id) AS databaseName , + type_desc, + mf.physical_name, + divfs.num_of_bytes_read, + divfs.num_of_bytes_written, + divfs.num_of_reads, + divfs.num_of_writes, + GETDATE() AS currentlineDate + FROM sys.dm_io_virtual_file_stats(NULL, NULL) AS divfs + INNER JOIN sys.master_files AS mf ON mf.database_id = divfs.database_id + AND mf.file_id = divfs.file_id +) + +SELECT database_name +, datafile_type +, num_of_bytes_read_persec = SUM(num_of_bytes_read_persec) +, num_of_bytes_written_persec = SUM(num_of_bytes_written_persec) +, num_of_reads_persec = SUM(num_of_reads_persec) +, num_of_writes_persec = SUM(num_of_writes_persec) +INTO #baselinewritten +FROM +( +SELECT + database_name = currentLine.databaseName +, datafile_type = type_desc +, num_of_bytes_read_persec = (currentLine.num_of_bytes_read - T1.num_of_bytes_read) / (DATEDIFF(SECOND,baseLineDate,currentLineDate)) +, num_of_bytes_written_persec = (currentLine.num_of_bytes_written - T1.num_of_bytes_written) / (DATEDIFF(SECOND,baseLineDate,currentLineDate)) +, num_of_reads_persec = (currentLine.num_of_reads - T1.num_of_reads) / (DATEDIFF(SECOND,baseLineDate,currentLineDate)) +, num_of_writes_persec = (currentLine.num_of_writes - T1.num_of_writes) / (DATEDIFF(SECOND,baseLineDate,currentLineDate)) +FROM currentLine +INNER JOIN #baseline T1 ON T1.databaseName = currentLine.databaseName + AND T1.physical_name = currentLine.physical_name +) as T +GROUP BY database_name, datafile_type + +DECLARE @DynamicPivotQuery AS NVARCHAR(MAX) +DECLARE @ColumnName AS NVARCHAR(MAX), @ColumnName2 AS NVARCHAR(MAX) +SELECT @ColumnName = ISNULL(@ColumnName + ',','') + QUOTENAME(database_name) + FROM (SELECT DISTINCT database_name FROM #baselinewritten) AS bl +SELECT @ColumnName2 = ISNULL(@ColumnName2 + '+','') + QUOTENAME(database_name) + FROM (SELECT DISTINCT database_name FROM #baselinewritten) AS bl + +SET @DynamicPivotQuery = N' +SELECT measurement = ''Log writes (bytes/sec)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''Database IO'' +, ' + @ColumnName + ', Total = ' + @ColumnName2 + ' FROM +( +SELECT database_name, num_of_bytes_written_persec +FROM #baselinewritten +WHERE datafile_type = ''LOG'' +) as V +PIVOT(SUM(num_of_bytes_written_persec) FOR database_name IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = ''Rows writes (bytes/sec)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''Database IO'' +, ' + @ColumnName + ', Total = ' + @ColumnName2 + ' FROM +( +SELECT database_name, num_of_bytes_written_persec +FROM #baselinewritten +WHERE datafile_type = ''ROWS'' +) as V +PIVOT(SUM(num_of_bytes_written_persec) FOR database_name IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = ''Log reads (bytes/sec)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''Database IO'' +, ' + @ColumnName + ', Total = ' + @ColumnName2 + ' FROM +( +SELECT database_name, num_of_bytes_read_persec +FROM #baselinewritten +WHERE datafile_type = ''LOG'' +) as V +PIVOT(SUM(num_of_bytes_read_persec) FOR database_name IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = ''Rows reads (bytes/sec)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''Database IO'' +, ' + @ColumnName + ', Total = ' + @ColumnName2 + ' FROM +( +SELECT database_name, num_of_bytes_read_persec +FROM #baselinewritten +WHERE datafile_type = ''ROWS'' +) as V +PIVOT(SUM(num_of_bytes_read_persec) FOR database_name IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = ''Log (writes/sec)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''Database IO'' +, ' + @ColumnName + ', Total = ' + @ColumnName2 + ' FROM +( +SELECT database_name, num_of_writes_persec +FROM #baselinewritten +WHERE datafile_type = ''LOG'' +) as V +PIVOT(SUM(num_of_writes_persec) FOR database_name IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = ''Rows (writes/sec)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''Database IO'' +, ' + @ColumnName + ', Total = ' + @ColumnName2 + ' FROM +( +SELECT database_name, num_of_writes_persec +FROM #baselinewritten +WHERE datafile_type = ''ROWS'' +) as V +PIVOT(SUM(num_of_writes_persec) FOR database_name IN (' + @ColumnName + ')) AS PVTTabl + +UNION ALL + +SELECT measurement = ''Log (reads/sec)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''Database IO'' +, ' + @ColumnName + ', Total = ' + @ColumnName2 + ' FROM +( +SELECT database_name, num_of_reads_persec +FROM #baselinewritten +WHERE datafile_type = ''LOG'' +) as V +PIVOT(SUM(num_of_reads_persec) FOR database_name IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = ''Rows (reads/sec)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''Database IO'' +, ' + @ColumnName + ', Total = ' + @ColumnName2 + ' FROM +( +SELECT database_name, num_of_reads_persec +FROM #baselinewritten +WHERE datafile_type = ''ROWS'' +) as V +PIVOT(SUM(num_of_reads_persec) FOR database_name IN (' + @ColumnName + ')) AS PVTTable +' + +EXEC sp_executesql @DynamicPivotQuery; +` + +const sqlDatabaseProperties string = `SET NOCOUNT ON; +SET ARITHABORT ON; +SET QUOTED_IDENTIFIER ON; +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED + +IF OBJECT_ID('tempdb..#Databases') IS NOT NULL + DROP TABLE #Databases; +CREATE TABLE #Databases +( + Measurement nvarchar(64) NOT NULL, + DatabaseName nvarchar(64) NOT NULL, + Value tinyint NOT NULL + Primary Key(DatabaseName, Measurement) +); + +INSERT #Databases ( Measurement, DatabaseName, Value) +SELECT + Measurement = 'Recovery Model FULL' +, DatabaseName = d.Name +, Value = CASE WHEN d.recovery_model = 1 THEN 1 ELSE 0 END +FROM sys.databases d +UNION ALL +SELECT + Measurement = 'Recovery Model BULK_LOGGED' +, DatabaseName = d.Name +, Value = CASE WHEN d.recovery_model = 2 THEN 1 ELSE 0 END +FROM sys.databases d +UNION ALL +SELECT + Measurement = 'Recovery Model SIMPLE' +, DatabaseName = d.Name +, Value = CASE WHEN d.recovery_model = 3 THEN 1 ELSE 0 END +FROM sys.databases d + +UNION ALL +SELECT + Measurement = 'State ONLINE' +, DatabaseName = d.Name +, Value = CASE WHEN d.state = 0 THEN 1 ELSE 0 END +FROM sys.databases d +UNION ALL +SELECT + Measurement = 'State RESTORING' +, DatabaseName = d.Name +, Value = CASE WHEN d.state = 1 THEN 1 ELSE 0 END +FROM sys.databases d +UNION ALL +SELECT + Measurement = 'State RECOVERING' +, DatabaseName = d.Name +, Value = CASE WHEN d.state = 2 THEN 1 ELSE 0 END +FROM sys.databases d +UNION ALL +SELECT + Measurement = 'State RECOVERY_PENDING' +, DatabaseName = d.Name +, Value = CASE WHEN d.state = 3 THEN 1 ELSE 0 END +FROM sys.databases d +UNION ALL +SELECT + Measurement = 'State SUSPECT' +, DatabaseName = d.Name +, Value = CASE WHEN d.state = 4 THEN 1 ELSE 0 END +FROM sys.databases d +UNION ALL +SELECT + Measurement = 'State EMERGENCY' +, DatabaseName = d.Name +, Value = CASE WHEN d.state = 5 THEN 1 ELSE 0 END +FROM sys.databases d +UNION ALL +SELECT + Measurement = 'State OFFLINE' +, DatabaseName = d.Name +, Value = CASE WHEN d.state = 6 THEN 1 ELSE 0 END +FROM sys.databases d + +DECLARE @DynamicPivotQuery AS NVARCHAR(MAX) +DECLARE @ColumnName AS NVARCHAR(MAX) +SELECT @ColumnName= ISNULL(@ColumnName + ',','') + QUOTENAME(DatabaseName) +FROM (SELECT DISTINCT DatabaseName FROM #Databases) AS bl + +SET @DynamicPivotQuery = N' +SELECT measurement = Measurement, servername = REPLACE(@@SERVERNAME, ''\'', '':'') +, type = ''Database properties'' +, ' + @ColumnName + ', total FROM +( +SELECT Measurement, DatabaseName, Value +, Total = (SELECT SUM(Value) FROM #Databases WHERE Measurement = d.Measurement) +FROM #Databases d +WHERE d.Measurement = ''Recovery Model FULL'' +) as V +PIVOT(SUM(Value) FOR DatabaseName IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = Measurement, servername = REPLACE(@@SERVERNAME, ''\'', '':'') +, type = ''Database properties'' +, ' + @ColumnName + ', total FROM +( +SELECT Measurement, DatabaseName, Value +, Total = (SELECT SUM(Value) FROM #Databases WHERE Measurement = d.Measurement) +FROM #Databases d +WHERE d.Measurement = ''Recovery Model BULK_LOGGED'' +) as V +PIVOT(SUM(Value) FOR DatabaseName IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = Measurement, servername = REPLACE(@@SERVERNAME, ''\'', '':'') +, type = ''Database properties'' +, ' + @ColumnName + ', total FROM +( +SELECT Measurement, DatabaseName, Value +, Total = (SELECT SUM(Value) FROM #Databases WHERE Measurement = d.Measurement) +FROM #Databases d +WHERE d.Measurement = ''Recovery Model SIMPLE'' +) as V +PIVOT(SUM(Value) FOR DatabaseName IN (' + @ColumnName + ')) AS PVTTable + + +UNION ALL + +SELECT measurement = Measurement, servername = REPLACE(@@SERVERNAME, ''\'', '':'') +, type = ''Database properties'' +, ' + @ColumnName + ', total FROM +( +SELECT Measurement, DatabaseName, Value +, Total = (SELECT SUM(Value) FROM #Databases WHERE Measurement = d.Measurement) +FROM #Databases d +WHERE d.Measurement = ''State ONLINE'' +) as V +PIVOT(SUM(Value) FOR DatabaseName IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = Measurement, servername = REPLACE(@@SERVERNAME, ''\'', '':'') +, type = ''Database properties'' +, ' + @ColumnName + ', total FROM +( +SELECT Measurement, DatabaseName, Value +, Total = (SELECT SUM(Value) FROM #Databases WHERE Measurement = d.Measurement) +FROM #Databases d +WHERE d.Measurement = ''State RESTORING'' +) as V +PIVOT(SUM(Value) FOR DatabaseName IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = Measurement, servername = REPLACE(@@SERVERNAME, ''\'', '':'') +, type = ''Database properties'' +, ' + @ColumnName + ', total FROM +( +SELECT Measurement, DatabaseName, Value +, Total = (SELECT SUM(Value) FROM #Databases WHERE Measurement = d.Measurement) +FROM #Databases d +WHERE d.Measurement = ''State RECOVERING'' +) as V +PIVOT(SUM(Value) FOR DatabaseName IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = Measurement, servername = REPLACE(@@SERVERNAME, ''\'', '':'') +, type = ''Database properties'' +, ' + @ColumnName + ', total FROM +( +SELECT Measurement, DatabaseName, Value +, Total = (SELECT SUM(Value) FROM #Databases WHERE Measurement = d.Measurement) +FROM #Databases d +WHERE d.Measurement = ''State RECOVERY_PENDING'' +) as V +PIVOT(SUM(Value) FOR DatabaseName IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = Measurement, servername = REPLACE(@@SERVERNAME, ''\'', '':'') +, type = ''Database properties'' +, ' + @ColumnName + ', total FROM +( +SELECT Measurement, DatabaseName, Value +, Total = (SELECT SUM(Value) FROM #Databases WHERE Measurement = d.Measurement) +FROM #Databases d +WHERE d.Measurement = ''State SUSPECT'' +) as V +PIVOT(SUM(Value) FOR DatabaseName IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = Measurement, servername = REPLACE(@@SERVERNAME, ''\'', '':'') +, type = ''Database properties'' +, ' + @ColumnName + ', total FROM +( +SELECT Measurement, DatabaseName, Value +, Total = (SELECT SUM(Value) FROM #Databases WHERE Measurement = d.Measurement) +FROM #Databases d +WHERE d.Measurement = ''State EMERGENCY'' +) as V +PIVOT(SUM(Value) FOR DatabaseName IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = Measurement, servername = REPLACE(@@SERVERNAME, ''\'', '':'') +, type = ''Database properties'' +, ' + @ColumnName + ', total FROM +( +SELECT Measurement, DatabaseName, Value +, Total = (SELECT SUM(Value) FROM #Databases WHERE Measurement = d.Measurement) +FROM #Databases d +WHERE d.Measurement = ''State OFFLINE'' +) as V +PIVOT(SUM(Value) FOR DatabaseName IN (' + @ColumnName + ')) AS PVTTable +' +EXEC sp_executesql @DynamicPivotQuery; +` + +const sqlCPUHistory string = `SET NOCOUNT ON; +SET ARITHABORT ON; +SET QUOTED_IDENTIFIER ON; +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; + +DECLARE @ms_ticks bigint; +SET @ms_ticks = (Select ms_ticks From sys.dm_os_sys_info); +DECLARE @maxEvents int = 1 + +SELECT +---- measurement + measurement = 'CPU (%)' +---- tags +, servername= REPLACE(@@SERVERNAME, '\', ':') +, type = 'CPU usage' +-- value +, [SQL process] = ProcessUtilization +, [External process]= 100 - SystemIdle - ProcessUtilization +, [SystemIdle] +FROM +( +SELECT TOP (@maxEvents) + EventTime = CAST(DateAdd(ms, -1 * (@ms_ticks - timestamp_ms), GetUTCDate()) as datetime) +, ProcessUtilization = CAST(ProcessUtilization as int) +, SystemIdle = CAST(SystemIdle as int) +FROM (SELECT Record.value('(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]', 'int') as SystemIdle, + Record.value('(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]', 'int') as ProcessUtilization, + timestamp as timestamp_ms +FROM (SELECT timestamp, convert(xml, record) As Record + FROM sys.dm_os_ring_buffers + WHERE ring_buffer_type = N'RING_BUFFER_SCHEDULER_MONITOR' + And record Like '%%') x) y +ORDER BY timestamp_ms Desc +) as T; +` + +const sqlPerformanceCounters string = `SET NOCOUNT ON; +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +IF OBJECT_ID('tempdb..#PCounters') IS NOT NULL DROP TABLE #PCounters +CREATE TABLE #PCounters +( + object_name nvarchar(128), + counter_name nvarchar(128), + instance_name nvarchar(128), + cntr_value bigint, + cntr_type INT, + Primary Key(object_name, counter_name, instance_name) +); +INSERT #PCounters +SELECT RTrim(spi.object_name) object_name +, RTrim(spi.counter_name) counter_name +, RTrim(spi.instance_name) instance_name +, spi.cntr_value +, spi.cntr_type +FROM sys.dm_os_performance_counters spi +WHERE spi.object_name NOT LIKE 'SQLServer:Backup Device%' + AND NOT EXISTS (SELECT 1 FROM sys.databases WHERE Name = spi.instance_name); + +WAITFOR DELAY '00:00:01'; + +IF OBJECT_ID('tempdb..#CCounters') IS NOT NULL DROP TABLE #CCounters +CREATE TABLE #CCounters +( + object_name nvarchar(128), + counter_name nvarchar(128), + instance_name nvarchar(128), + cntr_value bigint, + cntr_type INT, + Primary Key(object_name, counter_name, instance_name) +); +INSERT #CCounters +SELECT RTrim(spi.object_name) object_name +, RTrim(spi.counter_name) counter_name +, RTrim(spi.instance_name) instance_name +, spi.cntr_value +, spi.cntr_type +FROM sys.dm_os_performance_counters spi +WHERE spi.object_name NOT LIKE 'SQLServer:Backup Device%' + AND NOT EXISTS (SELECT 1 FROM sys.databases WHERE Name = spi.instance_name); + +SELECT + measurement = cc.counter_name + + CASE WHEN LEN(cc.instance_name) > 0 THEN ' | ' + cc.instance_name ELSE '' END + + ' | ' + + SUBSTRING( cc.object_name, CHARINDEX(':', cc.object_name) + 1, LEN( cc.object_name) - CHARINDEX(':', cc.object_name)) +-- tags +, servername = REPLACE(@@SERVERNAME, '\', ':') +, type = 'Performance counters' +--, countertype = CASE cc.cntr_type +-- When 65792 Then 'Count' +-- When 537003264 Then 'Ratio' +-- When 272696576 Then 'Per second' +-- When 1073874176 Then 'Average' +-- When 272696320 Then 'Average Per Second' +-- When 1073939712 Then 'Base' +-- END +-- value +, value = CAST(CASE cc.cntr_type + When 65792 Then cc.cntr_value -- Count + When 537003264 Then IsNull(Cast(cc.cntr_value as Money) / NullIf(cbc.cntr_value, 0), 0) -- Ratio + When 272696576 Then cc.cntr_value - pc.cntr_value -- Per Second + When 1073874176 Then IsNull(Cast(cc.cntr_value - pc.cntr_value as Money) / NullIf(cbc.cntr_value - pbc.cntr_value, 0), 0) -- Avg + When 272696320 Then IsNull(Cast(cc.cntr_value - pc.cntr_value as Money) / NullIf(cbc.cntr_value - pbc.cntr_value, 0), 0) -- Avg/sec + When 1073939712 Then cc.cntr_value - pc.cntr_value -- Base + Else cc.cntr_value End as int) +--, currentvalue= CAST(cc.cntr_value as bigint) +FROM #CCounters cc +INNER JOIN #PCounters pc On cc.object_name = pc.object_name + And cc.counter_name = pc.counter_name + And cc.instance_name = pc.instance_name + And cc.cntr_type = pc.cntr_type +LEFT JOIN #CCounters cbc On cc.object_name = cbc.object_name + And (Case When cc.counter_name Like '%(ms)' Then Replace(cc.counter_name, ' (ms)',' Base') + When cc.object_name = 'SQLServer:FileTable' Then Replace(cc.counter_name, 'Avg ','') + ' base' + When cc.counter_name = 'Worktables From Cache Ratio' Then 'Worktables From Cache Base' + When cc.counter_name = 'Avg. Length of Batched Writes' Then 'Avg. Length of Batched Writes BS' + Else cc.counter_name + ' base' + End) = cbc.counter_name + And cc.instance_name = cbc.instance_name + And cc.cntr_type In (537003264, 1073874176) + And cbc.cntr_type = 1073939712 +LEFT JOIN #PCounters pbc On pc.object_name = pbc.object_name + And pc.instance_name = pbc.instance_name + And (Case When pc.counter_name Like '%(ms)' Then Replace(pc.counter_name, ' (ms)',' Base') + When pc.object_name = 'SQLServer:FileTable' Then Replace(pc.counter_name, 'Avg ','') + ' base' + When pc.counter_name = 'Worktables From Cache Ratio' Then 'Worktables From Cache Base' + When pc.counter_name = 'Avg. Length of Batched Writes' Then 'Avg. Length of Batched Writes BS' + Else pc.counter_name + ' base' + End) = pbc.counter_name + And pc.cntr_type In (537003264, 1073874176) + +IF OBJECT_ID('tempdb..#CCounters') IS NOT NULL DROP TABLE #CCounters; +IF OBJECT_ID('tempdb..#PCounters') IS NOT NULL DROP TABLE #PCounters; +` + +const sqlWaitStatsCategorized string = `SET NOCOUNT ON; +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED +DECLARE @secondsBetween tinyint = 5 +DECLARE @delayInterval char(8) = CONVERT(Char(8), DATEADD(SECOND, @secondsBetween, '00:00:00'), 108); + +DECLARE @w1 TABLE +( + WaitType nvarchar(64) NOT NULL, + WaitTimeInMs bigint NOT NULL, + WaitTaskCount bigint NOT NULL, + CollectionDate datetime NOT NULL +) +DECLARE @w2 TABLE +( + WaitType nvarchar(64) NOT NULL, + WaitTimeInMs bigint NOT NULL, + WaitTaskCount bigint NOT NULL, + CollectionDate datetime NOT NULL +) +DECLARE @w3 TABLE +( + WaitType nvarchar(64) NOT NULL +) +DECLARE @w4 TABLE +( + WaitType nvarchar(64) NOT NULL, + WaitCategory nvarchar(64) NOT NULL +) +DECLARE @w5 TABLE +( + WaitCategory nvarchar(16) NOT NULL, + WaitTimeInMs bigint NOT NULL, + WaitTaskCount bigint NOT NULL +) + +INSERT @w3 (WaitType) +VALUES (N'QDS_SHUTDOWN_QUEUE'), (N'HADR_FILESTREAM_IOMGR_IOCOMPLETION'), + (N'BROKER_EVENTHANDLER'), (N'BROKER_RECEIVE_WAITFOR'), + (N'BROKER_TASK_STOP'), (N'BROKER_TO_FLUSH'), + (N'BROKER_TRANSMITTER'), (N'CHECKPOINT_QUEUE'), + (N'CHKPT'), (N'CLR_AUTO_EVENT'), + (N'CLR_MANUAL_EVENT'), (N'CLR_SEMAPHORE'), + (N'DBMIRROR_DBM_EVENT'), (N'DBMIRROR_EVENTS_QUEUE'), + (N'DBMIRROR_WORKER_QUEUE'), (N'DBMIRRORING_CMD'), + (N'DIRTY_PAGE_POLL'), (N'DISPATCHER_QUEUE_SEMAPHORE'), + (N'EXECSYNC'), (N'FSAGENT'), + (N'FT_IFTS_SCHEDULER_IDLE_WAIT'), (N'FT_IFTSHC_MUTEX'), + (N'HADR_CLUSAPI_CALL'), (N'HADR_FILESTREAM_IOMGR_IOCOMPLETIO(N'), + (N'HADR_LOGCAPTURE_WAIT'), (N'HADR_NOTIFICATION_DEQUEUE'), + (N'HADR_TIMER_TASK'), (N'HADR_WORK_QUEUE'), + (N'KSOURCE_WAKEUP'), (N'LAZYWRITER_SLEEP'), + (N'LOGMGR_QUEUE'), (N'ONDEMAND_TASK_QUEUE'), + (N'PWAIT_ALL_COMPONENTS_INITIALIZED'), + (N'QDS_PERSIST_TASK_MAIN_LOOP_SLEEP'), + (N'QDS_CLEANUP_STALE_QUERIES_TASK_MAIN_LOOP_SLEEP'), + (N'REQUEST_FOR_DEADLOCK_SEARCH'), (N'RESOURCE_QUEUE'), + (N'SERVER_IDLE_CHECK'), (N'SLEEP_BPOOL_FLUSH'), + (N'SLEEP_DBSTARTUP'), (N'SLEEP_DCOMSTARTUP'), + (N'SLEEP_MASTERDBREADY'), (N'SLEEP_MASTERMDREADY'), + (N'SLEEP_MASTERUPGRADED'), (N'SLEEP_MSDBSTARTUP'), + (N'SLEEP_SYSTEMTASK'), (N'SLEEP_TASK'), + (N'SLEEP_TEMPDBSTARTUP'), (N'SNI_HTTP_ACCEPT'), + (N'SP_SERVER_DIAGNOSTICS_SLEEP'), (N'SQLTRACE_BUFFER_FLUSH'), + (N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP'), + (N'SQLTRACE_WAIT_ENTRIES'), (N'WAIT_FOR_RESULTS'), + (N'WAITFOR'), (N'WAITFOR_TASKSHUTDOW(N'), + (N'WAIT_XTP_HOST_WAIT'), (N'WAIT_XTP_OFFLINE_CKPT_NEW_LOG'), + (N'WAIT_XTP_CKPT_CLOSE'), (N'XE_DISPATCHER_JOI(N'), + (N'XE_DISPATCHER_WAIT'), (N'XE_TIMER_EVENT'); + +INSERT @w4 (WaitType, WaitCategory) VALUES ('ABR', 'OTHER') , +('ASSEMBLY_LOAD' , 'OTHER') , ('ASYNC_DISKPOOL_LOCK' , 'I/O') , ('ASYNC_IO_COMPLETION' , 'I/O') , +('ASYNC_NETWORK_IO' , 'NETWORK') , ('AUDIT_GROUPCACHE_LOCK' , 'OTHER') , ('AUDIT_LOGINCACHE_LOCK' , +'OTHER') , ('AUDIT_ON_DEMAND_TARGET_LOCK' , 'OTHER') , ('AUDIT_XE_SESSION_MGR' , 'OTHER') , ('BACKUP' , +'BACKUP') , ('BACKUP_CLIENTLOCK ' , 'BACKUP') , ('BACKUP_OPERATOR' , 'BACKUP') , ('BACKUPBUFFER' , +'BACKUP') , ('BACKUPIO' , 'BACKUP') , ('BACKUPTHREAD' , 'BACKUP') , ('BAD_PAGE_PROCESS' , 'MEMORY') , +('BROKER_CONNECTION_RECEIVE_TASK' , 'SERVICE BROKER') , ('BROKER_ENDPOINT_STATE_MUTEX' , 'SERVICE BROKER') +, ('BROKER_EVENTHANDLER' , 'SERVICE BROKER') , ('BROKER_INIT' , 'SERVICE BROKER') , ('BROKER_MASTERSTART' +, 'SERVICE BROKER') , ('BROKER_RECEIVE_WAITFOR' , 'SERVICE BROKER') , ('BROKER_REGISTERALLENDPOINTS' , +'SERVICE BROKER') , ('BROKER_SERVICE' , 'SERVICE BROKER') , ('BROKER_SHUTDOWN' , 'SERVICE BROKER') , +('BROKER_TASK_STOP' , 'SERVICE BROKER') , ('BROKER_TO_FLUSH' , 'SERVICE BROKER') , ('BROKER_TRANSMITTER' , +'SERVICE BROKER') , ('BUILTIN_HASHKEY_MUTEX' , 'OTHER') , ('CHECK_PRINT_RECORD' , 'OTHER') , +('CHECKPOINT_QUEUE' , 'BUFFER') , ('CHKPT' , 'BUFFER') , ('CLEAR_DB' , 'OTHER') , ('CLR_AUTO_EVENT' , +'CLR') , ('CLR_CRST' , 'CLR') , ('CLR_JOIN' , 'CLR') , ('CLR_MANUAL_EVENT' , 'CLR') , ('CLR_MEMORY_SPY' , +'CLR') , ('CLR_MONITOR' , 'CLR') , ('CLR_RWLOCK_READER' , 'CLR') , ('CLR_RWLOCK_WRITER' , 'CLR') , +('CLR_SEMAPHORE' , 'CLR') , ('CLR_TASK_START' , 'CLR') , ('CLRHOST_STATE_ACCESS' , 'CLR') , ('CMEMTHREAD' +, 'MEMORY') , ('COMMIT_TABLE' , 'OTHER') , ('CURSOR' , 'OTHER') , ('CURSOR_ASYNC' , 'OTHER') , ('CXPACKET' +, 'OTHER') , ('CXROWSET_SYNC' , 'OTHER') , ('DAC_INIT' , 'OTHER') , ('DBMIRROR_DBM_EVENT ' , 'OTHER') , +('DBMIRROR_DBM_MUTEX ' , 'OTHER') , ('DBMIRROR_EVENTS_QUEUE' , 'OTHER') , ('DBMIRROR_SEND' , 'OTHER') , +('DBMIRROR_WORKER_QUEUE' , 'OTHER') , ('DBMIRRORING_CMD' , 'OTHER') , ('DBTABLE' , 'OTHER') , +('DEADLOCK_ENUM_MUTEX' , 'LOCK') , ('DEADLOCK_TASK_SEARCH' , 'LOCK') , ('DEBUG' , 'OTHER') , +('DISABLE_VERSIONING' , 'OTHER') , ('DISKIO_SUSPEND' , 'BACKUP') , ('DISPATCHER_QUEUE_SEMAPHORE' , +'OTHER') , ('DLL_LOADING_MUTEX' , 'XML') , ('DROPTEMP' , 'TEMPORARY OBJECTS') , ('DTC' , 'OTHER') , +('DTC_ABORT_REQUEST' , 'OTHER') , ('DTC_RESOLVE' , 'OTHER') , ('DTC_STATE' , 'DOTHERTC') , +('DTC_TMDOWN_REQUEST' , 'OTHER') , ('DTC_WAITFOR_OUTCOME' , 'OTHER') , ('DUMP_LOG_COORDINATOR' , 'OTHER') +, ('DUMP_LOG_COORDINATOR_QUEUE' , 'OTHER') , ('DUMPTRIGGER' , 'OTHER') , ('EC' , 'OTHER') , ('EE_PMOLOCK' +, 'MEMORY') , ('EE_SPECPROC_MAP_INIT' , 'OTHER') , ('ENABLE_VERSIONING' , 'OTHER') , +('ERROR_REPORTING_MANAGER' , 'OTHER') , ('EXCHANGE' , 'OTHER') , ('EXECSYNC' , 'OTHER') , +('EXECUTION_PIPE_EVENT_OTHER' , 'OTHER') , ('Failpoint' , 'OTHER') , ('FCB_REPLICA_READ' , 'OTHER') , +('FCB_REPLICA_WRITE' , 'OTHER') , ('FS_FC_RWLOCK' , 'OTHER') , ('FS_GARBAGE_COLLECTOR_SHUTDOWN' , 'OTHER') +, ('FS_HEADER_RWLOCK' , 'OTHER') , ('FS_LOGTRUNC_RWLOCK' , 'OTHER') , ('FSA_FORCE_OWN_XACT' , 'OTHER') , +('FSAGENT' , 'OTHER') , ('FSTR_CONFIG_MUTEX' , 'OTHER') , ('FSTR_CONFIG_RWLOCK' , 'OTHER') , +('FT_COMPROWSET_RWLOCK' , 'OTHER') , ('FT_IFTS_RWLOCK' , 'OTHER') , ('FT_IFTS_SCHEDULER_IDLE_WAIT' , +'OTHER') , ('FT_IFTSHC_MUTEX' , 'OTHER') , ('FT_IFTSISM_MUTEX' , 'OTHER') , ('FT_MASTER_MERGE' , 'OTHER') +, ('FT_METADATA_MUTEX' , 'OTHER') , ('FT_RESTART_CRAWL' , 'OTHER') , ('FT_RESUME_CRAWL' , 'OTHER') , +('FULLTEXT GATHERER' , 'OTHER') , ('GUARDIAN' , 'OTHER') , ('HTTP_ENDPOINT_COLLCREATE' , 'SERVICE BROKER') +, ('HTTP_ENUMERATION' , 'SERVICE BROKER') , ('HTTP_START' , 'SERVICE BROKER') , ('IMP_IMPORT_MUTEX' , +'OTHER') , ('IMPPROV_IOWAIT' , 'I/O') , ('INDEX_USAGE_STATS_MUTEX' , 'OTHER') , ('OTHER_TESTING' , +'OTHER') , ('IO_AUDIT_MUTEX' , 'OTHER') , ('IO_COMPLETION' , 'I/O') , ('IO_RETRY' , 'I/O') , +('IOAFF_RANGE_QUEUE' , 'OTHER') , ('KSOURCE_WAKEUP' , 'SHUTDOWN') , ('KTM_ENLISTMENT' , 'OTHER') , +('KTM_RECOVERY_MANAGER' , 'OTHER') , ('KTM_RECOVERY_RESOLUTION' , 'OTHER') , ('LATCH_DT' , 'LATCH') , +('LATCH_EX' , 'LATCH') , ('LATCH_KP' , 'LATCH') , ('LATCH_NL' , 'LATCH') , ('LATCH_SH' , 'LATCH') , +('LATCH_UP' , 'LATCH') , ('LAZYWRITER_SLEEP' , 'BUFFER') , ('LCK_M_BU' , 'LOCK') , ('LCK_M_IS' , 'LOCK') , +('LCK_M_IU' , 'LOCK') , ('LCK_M_IX' , 'LOCK') , ('LCK_M_RIn_NL' , 'LOCK') , ('LCK_M_RIn_S' , 'LOCK') , +('LCK_M_RIn_U' , 'LOCK') , ('LCK_M_RIn_X' , 'LOCK') , ('LCK_M_RS_S' , 'LOCK') , ('LCK_M_RS_U' , 'LOCK') , +('LCK_M_RX_S' , 'LOCK') , ('LCK_M_RX_U' , 'LOCK') , ('LCK_M_RX_X' , 'LOCK') , ('LCK_M_S' , 'LOCK') , +('LCK_M_SCH_M' , 'LOCK') , ('LCK_M_SCH_S' , 'LOCK') , ('LCK_M_SIU' , 'LOCK') , ('LCK_M_SIX' , 'LOCK') , +('LCK_M_U' , 'LOCK') , ('LCK_M_UIX' , 'LOCK') , ('LCK_M_X' , 'LOCK') , ('LOGBUFFER' , 'OTHER') , +('LOGGENERATION' , 'OTHER') , ('LOGMGR' , 'OTHER') , ('LOGMGR_FLUSH' , 'OTHER') , ('LOGMGR_QUEUE' , +'OTHER') , ('LOGMGR_RESERVE_APPEND' , 'OTHER') , ('LOWFAIL_MEMMGR_QUEUE' , 'MEMORY') , +('METADATA_LAZYCACHE_RWLOCK' , 'OTHER') , ('MIRROR_SEND_MESSAGE' , 'OTHER') , ('MISCELLANEOUS' , 'IGNORE') +, ('MSQL_DQ' , 'DISTRIBUTED QUERY') , ('MSQL_SYNC_PIPE' , 'OTHER') , ('MSQL_XACT_MGR_MUTEX' , 'OTHER') , +('MSQL_XACT_MUTEX' , 'OTHER') , ('MSQL_XP' , 'OTHER') , ('MSSEARCH' , 'OTHER') , ('NET_WAITFOR_PACKET' , +'NETWORK') , ('NODE_CACHE_MUTEX' , 'OTHER') , ('OTHER' , 'OTHER') , ('ONDEMAND_TASK_QUEUE' , 'OTHER') , +('PAGEIOLATCH_DT' , 'LATCH') , ('PAGEIOLATCH_EX' , 'LATCH') , ('PAGEIOLATCH_KP' , 'LATCH') , +('PAGEIOLATCH_NL' , 'LATCH') , ('PAGEIOLATCH_SH' , 'LATCH') , ('PAGEIOLATCH_UP' , 'LATCH') , +('PAGELATCH_DT' , 'LATCH') , ('PAGELATCH_EX' , 'LATCH') , ('PAGELATCH_KP' , 'LATCH') , ('PAGELATCH_NL' , +'LATCH') , ('PAGELATCH_SH' , 'LATCH') , ('PAGELATCH_UP' , 'LATCH') , ('PARALLEL_BACKUP_QUEUE' , 'BACKUP') +, ('PERFORMANCE_COUNTERS_RWLOCK' , 'OTHER') , ('PREEMPTIVE_ABR' , 'OTHER') , +('PREEMPTIVE_AUDIT_ACCESS_EVENTLOG' , 'OTHER') , ('PREEMPTIVE_AUDIT_ACCESS_SECLOG' , 'OTHER') , +('PREEMPTIVE_CLOSEBACKUPMEDIA' , 'OTHER') , ('PREEMPTIVE_CLOSEBACKUPTAPE' , 'OTHER') , +('PREEMPTIVE_CLOSEBACKUPVDIDEVICE' , 'OTHER') , ('PREEMPTIVE_CLUSAPI_CLUSTERRESOURCECONTROL' , 'OTHER') , +('PREEMPTIVE_COM_COCREATEINSTANCE' , 'OTHER') , ('PREEMPTIVE_COM_COGETCLASSOBJECT' , 'OTHER') , +('PREEMPTIVE_COM_CREATEACCESSOR' , 'OTHER') , ('PREEMPTIVE_COM_DELETEROWS' , 'OTHER') , +('PREEMPTIVE_COM_GETCOMMANDTEXT' , 'OTHER') , ('PREEMPTIVE_COM_GETDATA' , 'OTHER') , +('PREEMPTIVE_COM_GETNEXTROWS' , 'OTHER') , ('PREEMPTIVE_COM_GETRESULT' , 'OTHER') , +('PREEMPTIVE_COM_GETROWSBYBOOKMARK' , 'OTHER') , ('PREEMPTIVE_COM_LBFLUSH' , 'OTHER') , +('PREEMPTIVE_COM_LBLOCKREGION' , 'OTHER') , ('PREEMPTIVE_COM_LBREADAT' , 'OTHER') , +('PREEMPTIVE_COM_LBSETSIZE' , 'OTHER') , ('PREEMPTIVE_COM_LBSTAT' , 'OTHER') , +('PREEMPTIVE_COM_LBUNLOCKREGION' , 'OTHER') , ('PREEMPTIVE_COM_LBWRITEAT' , 'OTHER') , +('PREEMPTIVE_COM_QUERYINTERFACE' , 'OTHER') , ('PREEMPTIVE_COM_RELEASE' , 'OTHER') , +('PREEMPTIVE_COM_RELEASEACCESSOR' , 'OTHER') , ('PREEMPTIVE_COM_RELEASEROWS' , 'OTHER') , +('PREEMPTIVE_COM_RELEASESESSION' , 'OTHER') , ('PREEMPTIVE_COM_RESTARTPOSITION' , 'OTHER') , +('PREEMPTIVE_COM_SEQSTRMREAD' , 'OTHER') , ('PREEMPTIVE_COM_SEQSTRMREADANDWRITE' , 'OTHER') , +('PREEMPTIVE_COM_SETDATAFAILURE' , 'OTHER') , ('PREEMPTIVE_COM_SETPARAMETERINFO' , 'OTHER') , +('PREEMPTIVE_COM_SETPARAMETERPROPERTIES' , 'OTHER') , ('PREEMPTIVE_COM_STRMLOCKREGION' , 'OTHER') , +('PREEMPTIVE_COM_STRMSEEKANDREAD' , 'OTHER') , ('PREEMPTIVE_COM_STRMSEEKANDWRITE' , 'OTHER') , +('PREEMPTIVE_COM_STRMSETSIZE' , 'OTHER') , ('PREEMPTIVE_COM_STRMSTAT' , 'OTHER') , +('PREEMPTIVE_COM_STRMUNLOCKREGION' , 'OTHER') , ('PREEMPTIVE_CONSOLEWRITE' , 'OTHER') , +('PREEMPTIVE_CREATEPARAM' , 'OTHER') , ('PREEMPTIVE_DEBUG' , 'OTHER') , ('PREEMPTIVE_DFSADDLINK' , +'OTHER') , ('PREEMPTIVE_DFSLINKEXISTCHECK' , 'OTHER') , ('PREEMPTIVE_DFSLINKHEALTHCHECK' , 'OTHER') , +('PREEMPTIVE_DFSREMOVELINK' , 'OTHER') , ('PREEMPTIVE_DFSREMOVEROOT' , 'OTHER') , +('PREEMPTIVE_DFSROOTFOLDERCHECK' , 'OTHER') , ('PREEMPTIVE_DFSROOTINIT' , 'OTHER') , +('PREEMPTIVE_DFSROOTSHARECHECK' , 'OTHER') , ('PREEMPTIVE_DTC_ABORT' , 'OTHER') , +('PREEMPTIVE_DTC_ABORTREQUESTDONE' , 'OTHER') , ('PREEMPTIVE_DTC_BEGINOTHER' , 'OTHER') , +('PREEMPTIVE_DTC_COMMITREQUESTDONE' , 'OTHER') , ('PREEMPTIVE_DTC_ENLIST' , 'OTHER') , +('PREEMPTIVE_DTC_PREPAREREQUESTDONE' , 'OTHER') , ('PREEMPTIVE_FILESIZEGET' , 'OTHER') , +('PREEMPTIVE_FSAOTHER_ABORTOTHER' , 'OTHER') , ('PREEMPTIVE_FSAOTHER_COMMITOTHER' , 'OTHER') , +('PREEMPTIVE_FSAOTHER_STARTOTHER' , 'OTHER') , ('PREEMPTIVE_FSRECOVER_UNCONDITIONALUNDO' , 'OTHER') , +('PREEMPTIVE_GETRMINFO' , 'OTHER') , ('PREEMPTIVE_LOCKMONITOR' , 'OTHER') , ('PREEMPTIVE_MSS_RELEASE' , +'OTHER') , ('PREEMPTIVE_ODBCOPS' , 'OTHER') , ('PREEMPTIVE_OLE_UNINIT' , 'OTHER') , +('PREEMPTIVE_OTHER_ABORTORCOMMITTRAN' , 'OTHER') , ('PREEMPTIVE_OTHER_ABORTTRAN' , 'OTHER') , +('PREEMPTIVE_OTHER_GETDATASOURCE' , 'OTHER') , ('PREEMPTIVE_OTHER_GETLITERALINFO' , 'OTHER') , +('PREEMPTIVE_OTHER_GETPROPERTIES' , 'OTHER') , ('PREEMPTIVE_OTHER_GETPROPERTYINFO' , 'OTHER') , +('PREEMPTIVE_OTHER_GETSCHEMALOCK' , 'OTHER') , ('PREEMPTIVE_OTHER_JOINOTHER' , 'OTHER') , +('PREEMPTIVE_OTHER_RELEASE' , 'OTHER') , ('PREEMPTIVE_OTHER_SETPROPERTIES' , 'OTHER') , +('PREEMPTIVE_OTHEROPS' , 'OTHER') , ('PREEMPTIVE_OS_ACCEPTSECURITYCONTEXT' , 'OTHER') , +('PREEMPTIVE_OS_ACQUIRECREDENTIALSHANDLE' , 'OTHER') , ('PREEMPTIVE_OS_AU,TICATIONOPS' , 'OTHER') , +('PREEMPTIVE_OS_AUTHORIZATIONOPS' , 'OTHER') , ('PREEMPTIVE_OS_AUTHZGETINFORMATIONFROMCONTEXT' , 'OTHER') +, ('PREEMPTIVE_OS_AUTHZINITIALIZECONTEXTFROMSID' , 'OTHER') , +('PREEMPTIVE_OS_AUTHZINITIALIZERESOURCEMANAGER' , 'OTHER') , ('PREEMPTIVE_OS_BACKUPREAD' , 'OTHER') , +('PREEMPTIVE_OS_CLOSEHANDLE' , 'OTHER') , ('PREEMPTIVE_OS_CLUSTEROPS' , 'OTHER') , ('PREEMPTIVE_OS_COMOPS' +, 'OTHER') , ('PREEMPTIVE_OS_COMPLETEAUTHTOKEN' , 'OTHER') , ('PREEMPTIVE_OS_COPYFILE' , 'OTHER') , +('PREEMPTIVE_OS_CREATEDIRECTORY' , 'OTHER') , ('PREEMPTIVE_OS_CREATEFILE' , 'OTHER') , +('PREEMPTIVE_OS_CRYPTACQUIRECONTEXT' , 'OTHER') , ('PREEMPTIVE_OS_CRYPTIMPORTKEY' , 'OTHER') , +('PREEMPTIVE_OS_CRYPTOPS' , 'OTHER') , ('PREEMPTIVE_OS_DECRYPTMESSAGE' , 'OTHER') , +('PREEMPTIVE_OS_DELETEFILE' , 'OTHER') , ('PREEMPTIVE_OS_DELETESECURITYCONTEXT' , 'OTHER') , +('PREEMPTIVE_OS_DEVICEIOCONTROL' , 'OTHER') , ('PREEMPTIVE_OS_DEVICEOPS' , 'OTHER') , +('PREEMPTIVE_OS_DIRSVC_NETWORKOPS' , 'OTHER') , ('PREEMPTIVE_OS_DISCONNECTNAMEDPIPE' , 'OTHER') , +('PREEMPTIVE_OS_DOMAINSERVICESOPS' , 'OTHER') , ('PREEMPTIVE_OS_DSGETDCNAME' , 'OTHER') , +('PREEMPTIVE_OS_DTCOPS' , 'OTHER') , ('PREEMPTIVE_OS_ENCRYPTMESSAGE' , 'OTHER') , ('PREEMPTIVE_OS_FILEOPS' +, 'OTHER') , ('PREEMPTIVE_OS_FINDFILE' , 'OTHER') , ('PREEMPTIVE_OS_FLUSHFILEBUFFERS' , 'OTHER') , +('PREEMPTIVE_OS_FORMATMESSAGE' , 'OTHER') , ('PREEMPTIVE_OS_FREECREDENTIALSHANDLE' , 'OTHER') , +('PREEMPTIVE_OS_FREELIBRARY' , 'OTHER') , ('PREEMPTIVE_OS_GENERICOPS' , 'OTHER') , +('PREEMPTIVE_OS_GETADDRINFO' , 'OTHER') , ('PREEMPTIVE_OS_GETCOMPRESSEDFILESIZE' , 'OTHER') , +('PREEMPTIVE_OS_GETDISKFREESPACE' , 'OTHER') , ('PREEMPTIVE_OS_GETFILEATTRIBUTES' , 'OTHER') , +('PREEMPTIVE_OS_GETFILESIZE' , 'OTHER') , ('PREEMPTIVE_OS_GETLONGPATHNAME' , 'OTHER') , +('PREEMPTIVE_OS_GETPROCADDRESS' , 'OTHER') , ('PREEMPTIVE_OS_GETVOLUMENAMEFORVOLUMEMOUNTPOINT' , 'OTHER') +, ('PREEMPTIVE_OS_GETVOLUMEPATHNAME' , 'OTHER') , ('PREEMPTIVE_OS_INITIALIZESECURITYCONTEXT' , 'OTHER') , +('PREEMPTIVE_OS_LIBRARYOPS' , 'OTHER') , ('PREEMPTIVE_OS_LOADLIBRARY' , 'OTHER') , +('PREEMPTIVE_OS_LOGONUSER' , 'OTHER') , ('PREEMPTIVE_OS_LOOKUPACCOUNTSID' , 'OTHER') , +('PREEMPTIVE_OS_MESSAGEQUEUEOPS' , 'OTHER') , ('PREEMPTIVE_OS_MOVEFILE' , 'OTHER') , +('PREEMPTIVE_OS_NETGROUPGETUSERS' , 'OTHER') , ('PREEMPTIVE_OS_NETLOCALGROUPGETMEMBERS' , 'OTHER') , +('PREEMPTIVE_OS_NETUSERGETGROUPS' , 'OTHER') , ('PREEMPTIVE_OS_NETUSERGETLOCALGROUPS' , 'OTHER') , +('PREEMPTIVE_OS_NETUSERMODALSGET' , 'OTHER') , ('PREEMPTIVE_OS_NETVALIDATEPASSWORDPOLICY' , 'OTHER') , +('PREEMPTIVE_OS_NETVALIDATEPASSWORDPOLICYFREE' , 'OTHER') , ('PREEMPTIVE_OS_OPENDIRECTORY' , 'OTHER') , +('PREEMPTIVE_OS_PIPEOPS' , 'OTHER') , ('PREEMPTIVE_OS_PROCESSOPS' , 'OTHER') , +('PREEMPTIVE_OS_QUERYREGISTRY' , 'OTHER') , ('PREEMPTIVE_OS_QUERYSECURITYCONTEXTTOKEN' , 'OTHER') , +('PREEMPTIVE_OS_REMOVEDIRECTORY' , 'OTHER') , ('PREEMPTIVE_OS_REPORTEVENT' , 'OTHER') , +('PREEMPTIVE_OS_REVERTTOSELF' , 'OTHER') , ('PREEMPTIVE_OS_RSFXDEVICEOPS' , 'OTHER') , +('PREEMPTIVE_OS_SECURITYOPS' , 'OTHER') , ('PREEMPTIVE_OS_SERVICEOPS' , 'OTHER') , +('PREEMPTIVE_OS_SETENDOFFILE' , 'OTHER') , ('PREEMPTIVE_OS_SETFILEPOINTER' , 'OTHER') , +('PREEMPTIVE_OS_SETFILEVALIDDATA' , 'OTHER') , ('PREEMPTIVE_OS_SETNAMEDSECURITYINFO' , 'OTHER') , +('PREEMPTIVE_OS_SQLCLROPS' , 'OTHER') , ('PREEMPTIVE_OS_SQMLAUNCH' , 'OTHER') , +('PREEMPTIVE_OS_VERIFYSIGNATURE' , 'OTHER') , ('PREEMPTIVE_OS_VSSOPS' , 'OTHER') , +('PREEMPTIVE_OS_WAITFORSINGLEOBJECT' , 'OTHER') , ('PREEMPTIVE_OS_WINSOCKOPS' , 'OTHER') , +('PREEMPTIVE_OS_WRITEFILE' , 'OTHER') , ('PREEMPTIVE_OS_WRITEFILEGATHER' , 'OTHER') , +('PREEMPTIVE_OS_WSASETLASTERROR' , 'OTHER') , ('PREEMPTIVE_REENLIST' , 'OTHER') , ('PREEMPTIVE_RESIZELOG' +, 'OTHER') , ('PREEMPTIVE_ROLLFORWARDREDO' , 'OTHER') , ('PREEMPTIVE_ROLLFORWARDUNDO' , 'OTHER') , +('PREEMPTIVE_SB_STOPENDPOINT' , 'OTHER') , ('PREEMPTIVE_SERVER_STARTUP' , 'OTHER') , +('PREEMPTIVE_SETRMINFO' , 'OTHER') , ('PREEMPTIVE_SHAREDMEM_GETDATA' , 'OTHER') , ('PREEMPTIVE_SNIOPEN' , +'OTHER') , ('PREEMPTIVE_SOSHOST' , 'OTHER') , ('PREEMPTIVE_SOSTESTING' , 'OTHER') , ('PREEMPTIVE_STARTRM' +, 'OTHER') , ('PREEMPTIVE_STREAMFCB_CHECKPOINT' , 'OTHER') , ('PREEMPTIVE_STREAMFCB_RECOVER' , 'OTHER') , +('PREEMPTIVE_STRESSDRIVER' , 'OTHER') , ('PREEMPTIVE_TESTING' , 'OTHER') , ('PREEMPTIVE_TRANSIMPORT' , +'OTHER') , ('PREEMPTIVE_UNMARSHALPROPAGATIONTOKEN' , 'OTHER') , ('PREEMPTIVE_VSS_CREATESNAPSHOT' , +'OTHER') , ('PREEMPTIVE_VSS_CREATEVOLUMESNAPSHOT' , 'OTHER') , ('PREEMPTIVE_XE_CALLBACKEXECUTE' , 'OTHER') +, ('PREEMPTIVE_XE_DISPATCHER' , 'OTHER') , ('PREEMPTIVE_XE_ENGINEINIT' , 'OTHER') , +('PREEMPTIVE_XE_GETTARGETSTATE' , 'OTHER') , ('PREEMPTIVE_XE_SESSIONCOMMIT' , 'OTHER') , +('PREEMPTIVE_XE_TARGETFINALIZE' , 'OTHER') , ('PREEMPTIVE_XE_TARGETINIT' , 'OTHER') , +('PREEMPTIVE_XE_TIMERRUN' , 'OTHER') , ('PREEMPTIVE_XETESTING' , 'OTHER') , ('PREEMPTIVE_XXX' , 'OTHER') , +('PRINT_ROLLBACK_PROGRESS' , 'OTHER') , ('QNMANAGER_ACQUIRE' , 'OTHER') , ('QPJOB_KILL' , 'OTHER') , +('QPJOB_WAITFOR_ABORT' , 'OTHER') , ('QRY_MEM_GRANT_INFO_MUTEX' , 'OTHER') , ('QUERY_ERRHDL_SERVICE_DONE' +, 'OTHER') , ('QUERY_EXECUTION_INDEX_SORT_EVENT_OPEN' , 'OTHER') , ('QUERY_NOTIFICATION_MGR_MUTEX' , +'OTHER') , ('QUERY_NOTIFICATION_SUBSCRIPTION_MUTEX' , 'OTHER') , ('QUERY_NOTIFICATION_TABLE_MGR_MUTEX' , +'OTHER') , ('QUERY_NOTIFICATION_UNITTEST_MUTEX' , 'OTHER') , ('QUERY_OPTIMIZER_PRINT_MUTEX' , 'OTHER') , +('QUERY_TRACEOUT' , 'OTHER') , ('QUERY_WAIT_ERRHDL_SERVICE' , 'OTHER') , ('RECOVER_CHANGEDB' , 'OTHER') , +('REPL_CACHE_ACCESS' , 'REPLICATION') , ('REPL_HISTORYCACHE_ACCESS' , 'OTHER') , ('REPL_SCHEMA_ACCESS' , +'OTHER') , ('REPL_TRANHASHTABLE_ACCESS' , 'OTHER') , ('REPLICA_WRITES' , 'OTHER') , +('REQUEST_DISPENSER_PAUSE' , 'BACKUP') , ('REQUEST_FOR_DEADLOCK_SEARCH' , 'LOCK') , ('RESMGR_THROTTLED' , +'OTHER') , ('RESOURCE_QUERY_SEMAPHORE_COMPILE' , 'QUERY') , ('RESOURCE_QUEUE' , 'OTHER') , +('RESOURCE_SEMAPHORE' , 'OTHER') , ('RESOURCE_SEMAPHORE_MUTEX' , 'MEMORY') , +('RESOURCE_SEMAPHORE_QUERY_COMPILE' , 'MEMORY') , ('RESOURCE_SEMAPHORE_SMALL_QUERY' , 'MEMORY') , +('RG_RECONFIG' , 'OTHER') , ('SEC_DROP_TEMP_KEY' , 'SECURITY') , ('SECURITY_MUTEX' , 'OTHER') , +('SEQUENTIAL_GUID' , 'OTHER') , ('SERVER_IDLE_CHECK' , 'OTHER') , ('SHUTDOWN' , 'OTHER') , +('SLEEP_BPOOL_FLUSH' , 'OTHER') , ('SLEEP_DBSTARTUP' , 'OTHER') , ('SLEEP_DCOMSTARTUP' , 'OTHER') , +('SLEEP_MSDBSTARTUP' , 'OTHER') , ('SLEEP_SYSTEMTASK' , 'OTHER') , ('SLEEP_TASK' , 'OTHER') , +('SLEEP_TEMPDBSTARTUP' , 'OTHER') , ('SNI_CRITICAL_SECTION' , 'OTHER') , ('SNI_HTTP_ACCEPT' , 'OTHER') , +('SNI_HTTP_WAITFOR_0_DISCON' , 'OTHER') , ('SNI_LISTENER_ACCESS' , 'OTHER') , ('SNI_TASK_COMPLETION' , +'OTHER') , ('SOAP_READ' , 'OTHER') , ('SOAP_WRITE' , 'OTHER') , ('SOS_CALLBACK_REMOVAL' , 'OTHER') , +('SOS_DISPATCHER_MUTEX' , 'OTHER') , ('SOS_LOCALALLOCATORLIST' , 'OTHER') , ('SOS_MEMORY_USAGE_ADJUSTMENT' +, 'OTHER') , ('SOS_OBJECT_STORE_DESTROY_MUTEX' , 'OTHER') , ('SOS_PROCESS_AFFINITY_MUTEX' , 'OTHER') , +('SOS_RESERVEDMEMBLOCKLIST' , 'OTHER') , ('SOS_SCHEDULER_YIELD' , 'SQLOS') , ('SOS_SMALL_PAGE_ALLOC' , +'OTHER') , ('SOS_STACKSTORE_INIT_MUTEX' , 'OTHER') , ('SOS_SYNC_TASK_ENQUEUE_EVENT' , 'OTHER') , +('SOS_VIRTUALMEMORY_LOW' , 'OTHER') , ('SOSHOST_EVENT' , 'CLR') , ('SOSHOST_OTHER' , 'CLR') , +('SOSHOST_MUTEX' , 'CLR') , ('SOSHOST_ROWLOCK' , 'CLR') , ('SOSHOST_RWLOCK' , 'CLR') , +('SOSHOST_SEMAPHORE' , 'CLR') , ('SOSHOST_SLEEP' , 'CLR') , ('SOSHOST_TRACELOCK' , 'CLR') , +('SOSHOST_WAITFORDONE' , 'CLR') , ('SQLCLR_APPDOMAIN' , 'CLR') , ('SQLCLR_ASSEMBLY' , 'CLR') , +('SQLCLR_DEADLOCK_DETECTION' , 'CLR') , ('SQLCLR_QUANTUM_PUNISHMENT' , 'CLR') , ('SQLSORT_NORMMUTEX' , +'OTHER') , ('SQLSORT_SORTMUTEX' , 'OTHER') , ('SQLTRACE_BUFFER_FLUSH ' , 'TRACE') , ('SQLTRACE_LOCK' , +'OTHER') , ('SQLTRACE_SHUTDOWN' , 'OTHER') , ('SQLTRACE_WAIT_ENTRIES' , 'OTHER') , ('SRVPROC_SHUTDOWN' , +'OTHER') , ('TEMPOBJ' , 'OTHER') , ('THREADPOOL' , 'SQLOS') , ('TIMEPRIV_TIMEPERIOD' , 'OTHER') , +('TRACE_EVTNOTIF' , 'OTHER') , ('TRACEWRITE' , 'OTHER') , ('TRAN_MARKLATCH_DT' , 'TRAN_MARKLATCH') , +('TRAN_MARKLATCH_EX' , 'TRAN_MARKLATCH') , ('TRAN_MARKLATCH_KP' , 'TRAN_MARKLATCH') , ('TRAN_MARKLATCH_NL' +, 'TRAN_MARKLATCH') , ('TRAN_MARKLATCH_SH' , 'TRAN_MARKLATCH') , ('TRAN_MARKLATCH_UP' , 'TRAN_MARKLATCH') +, ('OTHER_MUTEX' , 'OTHER') , ('UTIL_PAGE_ALLOC' , 'OTHER') , ('VIA_ACCEPT' , 'OTHER') , +('VIEW_DEFINITION_MUTEX' , 'OTHER') , ('WAIT_FOR_RESULTS' , 'OTHER') , ('WAITFOR' , 'WAITFOR') , +('WAITFOR_TASKSHUTDOWN' , 'OTHER') , ('WAITSTAT_MUTEX' , 'OTHER') , ('WCC' , 'OTHER') , ('WORKTBL_DROP' , +'OTHER') , ('WRITE_COMPLETION' , 'OTHER') , ('WRITELOG' , 'I/O') , ('XACT_OWN_OTHER' , 'OTHER') , +('XACT_RECLAIM_SESSION' , 'OTHER') , ('XACTLOCKINFO' , 'OTHER') , ('XACTWORKSPACE_MUTEX' , 'OTHER') , +('XE_BUFFERMGR_ALLPROCESSED_EVENT' , 'XEVENT') , ('XE_BUFFERMGR_FREEBUF_EVENT' , 'XEVENT') , +('XE_DISPATCHER_CONFIG_SESSION_LIST' , 'XEVENT') , ('XE_DISPATCHER_JOIN' , 'XEVENT') , +('XE_DISPATCHER_WAIT' , 'XEVENT') , ('XE_MODULEMGR_SYNC' , 'XEVENT') , ('XE_OLS_LOCK' , 'XEVENT') , +('XE_PACKAGE_LOCK_BACKOFF' , 'XEVENT') , ('XE_SERVICES_EVENTMANUAL' , 'XEVENT') , ('XE_SERVICES_MUTEX' , +'XEVENT') , ('XE_SERVICES_RWLOCK' , 'XEVENT') , ('XE_SESSION_CREATE_SYNC' , 'XEVENT') , +('XE_SESSION_FLUSH' , 'XEVENT') , ('XE_SESSION_SYNC' , 'XEVENT') , ('XE_STM_CREATE' , 'XEVENT') , +('XE_TIMER_EVENT' , 'XEVENT') , ('XE_TIMER_MUTEX' , 'XEVENT') +, ('XE_TIMER_TASK_DONE' , 'XEVENT'); + + +INSERT @w1 (WaitType, WaitTimeInMs, WaitTaskCount, CollectionDate) +SELECT + WaitType = wait_type +, WaitTimeInMs = SUM(wait_time_ms) +, WaitTaskCount = SUM(waiting_tasks_count) +, CollectionDate = GETDATE() +FROM sys.dm_os_wait_stats +WHERE [wait_type] NOT IN +( + SELECT WaitType FROM @w3 +) +AND [waiting_tasks_count] > 0 +GROUP BY wait_type + +WAITFOR DELAY @delayInterval; + +INSERT @w2 (WaitType, WaitTimeInMs, WaitTaskCount, CollectionDate) +SELECT + WaitType = wait_type +, WaitTimeInMs = SUM(wait_time_ms) +, WaitTaskCount = SUM(waiting_tasks_count) +, CollectionDate = GETDATE() +FROM sys.dm_os_wait_stats +WHERE [wait_type] NOT IN +( + SELECT WaitType FROM @w3 +) +AND [waiting_tasks_count] > 0 +GROUP BY wait_type; + + +INSERT @w5 (WaitCategory, WaitTimeInMs, WaitTaskCount) +SELECT WaitCategory +, WaitTimeInMs = SUM(WaitTimeInMs) +, WaitTaskCount = SUM(WaitTaskCount) +FROM +( +SELECT + WaitCategory = ISNULL(T4.WaitCategory, 'OTHER') +, WaitTimeInMs = (T2.WaitTimeInMs - T1.WaitTimeInMs) +, WaitTaskCount = (T2.WaitTaskCount - T1.WaitTaskCount) +--, WaitTimeInMsPerSec = ((T2.WaitTimeInMs - T1.WaitTimeInMs) / CAST(DATEDIFF(SECOND, T1.CollectionDate, T2.CollectionDate) as float)) +FROM @w1 T1 +INNER JOIN @w2 T2 ON T2.WaitType = T1.WaitType +LEFT JOIN @w4 T4 ON T4.WaitType = T1.WaitType +WHERE T2.WaitTaskCount - T1.WaitTaskCount > 0 +) as G +GROUP BY G.WaitCategory; + + + +SELECT +---- measurement + measurement = 'Wait time (ms)' +---- tags +, servername= REPLACE(@@SERVERNAME, '\', ':') +, type = 'Wait stats' +---- values +, [I/O] = SUM([I/O]) +, [Latch] = SUM([Latch]) +, [Lock] = SUM([Lock]) +, [Network] = SUM([Network]) +, [Service broker] = SUM([Service broker]) +, [Memory] = SUM([Memory]) +, [Buffer] = SUM([Buffer]) +, [CLR] = SUM([CLR]) +, [SQLOS] = SUM([SQLOS]) +, [XEvent] = SUM([XEvent]) +, [Other] = SUM([Other]) +, [Total] = SUM([I/O]+[LATCH]+[LOCK]+[NETWORK]+[SERVICE BROKER]+[MEMORY]+[BUFFER]+[CLR]+[XEVENT]+[SQLOS]+[OTHER]) +FROM +( +SELECT + [I/O] = ISNULL([I/O] , 0) +, [MEMORY] = ISNULL([MEMORY] , 0) +, [BUFFER] = ISNULL([BUFFER] , 0) +, [LATCH] = ISNULL([LATCH] , 0) +, [LOCK] = ISNULL([LOCK] , 0) +, [NETWORK] = ISNULL([NETWORK] , 0) +, [SERVICE BROKER] = ISNULL([SERVICE BROKER] , 0) +, [CLR] = ISNULL([CLR] , 0) +, [XEVENT] = ISNULL([XEVENT] , 0) +, [SQLOS] = ISNULL([SQLOS] , 0) +, [OTHER] = ISNULL([OTHER] , 0) +FROM @w5 as P +PIVOT +( + SUM(WaitTimeInMs) + FOR WaitCategory IN ([I/O], [LATCH], [LOCK], [NETWORK], [SERVICE BROKER], [MEMORY], [BUFFER], [CLR], [XEVENT], [SQLOS], [OTHER]) +) AS PivotTable +) as T + +UNION ALL + +SELECT +---- measurement + measurement = 'Wait tasks' +---- tags +, server_name= REPLACE(@@SERVERNAME, '\', ':') +, type = 'Wait stats' +---- values +, [I/O] = SUM([I/O]) +, [Latch] = SUM([Latch]) +, [Lock] = SUM([Lock]) +, [Network] = SUM([Network]) +, [Service broker] = SUM([Service broker]) +, [Memory] = SUM([Memory]) +, [Buffer] = SUM([Buffer]) +, [CLR] = SUM([CLR]) +, [SQLOS] = SUM([SQLOS]) +, [XEvent] = SUM([XEvent]) +, [Other] = SUM([Other]) +, [Total] = SUM([I/O]+[LATCH]+[LOCK]+[NETWORK]+[SERVICE BROKER]+[MEMORY]+[BUFFER]+[CLR]+[XEVENT]+[SQLOS]+[OTHER]) +FROM +( +SELECT + [I/O] = ISNULL([I/O] , 0) +, [MEMORY] = ISNULL([MEMORY] , 0) +, [BUFFER] = ISNULL([BUFFER] , 0) +, [LATCH] = ISNULL([LATCH] , 0) +, [LOCK] = ISNULL([LOCK] , 0) +, [NETWORK] = ISNULL([NETWORK] , 0) +, [SERVICE BROKER] = ISNULL([SERVICE BROKER] , 0) +, [CLR] = ISNULL([CLR] , 0) +, [XEVENT] = ISNULL([XEVENT] , 0) +, [SQLOS] = ISNULL([SQLOS] , 0) +, [OTHER] = ISNULL([OTHER] , 0) +FROM @w5 as P +PIVOT +( + SUM(WaitTaskCount) + FOR WaitCategory IN ([I/O], [LATCH], [LOCK], [NETWORK], [SERVICE BROKER], [MEMORY], [BUFFER], [CLR], [XEVENT], [SQLOS], [OTHER]) +) AS PivotTable +) as T; +` + +const sqlVolumeSpace string = `SET NOCOUNT ON; +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; + +IF OBJECT_ID('tempdb..#volumestats') IS NOT NULL + DROP TABLE #volumestats; +SELECT DISTINCT + volume = REPLACE(vs.volume_mount_point, '\', '') + + CASE WHEN LEN(vs.logical_volume_name) > 0 + THEN ' (' + vs.logical_volume_name + ')' + ELSE '' END +, total_bytes = vs.total_bytes +, available_bytes = vs.available_bytes +, used_bytes = vs.total_bytes - vs.available_bytes +, used_percent = 100 * CAST(ROUND((vs.total_bytes - vs.available_bytes) * 1. / vs.total_bytes, 2) as decimal(5,2)) +INTO #volumestats +FROM sys.master_files AS f +CROSS APPLY sys.dm_os_volume_stats(f.database_id, f.file_id) vs + +DECLARE @DynamicPivotQuery AS NVARCHAR(MAX) +DECLARE @ColumnName AS NVARCHAR(MAX), @ColumnName2 AS NVARCHAR(MAX) + +SELECT @ColumnName= ISNULL(@ColumnName + ',','') + QUOTENAME(volume) +FROM (SELECT DISTINCT volume FROM #volumestats) AS bl + +--Prepare the PIVOT query using the dynamic +SET @DynamicPivotQuery = N' +SELECT measurement = ''Volume total space (bytes)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''OS Volume space'' +, ' + @ColumnName + ' FROM +( +SELECT volume, total_bytes +FROM #volumestats +) as V +PIVOT(SUM(total_bytes) FOR volume IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = ''Volume available space (bytes)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''OS Volume space'' +, ' + @ColumnName + ' FROM +( +SELECT volume, available_bytes +FROM #volumestats +) as V +PIVOT(SUM(available_bytes) FOR volume IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = ''Volume used space (bytes)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''OS Volume space'' +, ' + @ColumnName + ' FROM +( +SELECT volume, used_bytes +FROM #volumestats +) as V +PIVOT(SUM(used_bytes) FOR volume IN (' + @ColumnName + ')) AS PVTTable + +UNION ALL + +SELECT measurement = ''Volume used space (%)'', servername = REPLACE(@@SERVERNAME, ''\'', '':''), type = ''OS Volume space'' +, ' + @ColumnName + ' FROM +( +SELECT volume, used_percent +FROM #volumestats +) as V +PIVOT(SUM(used_percent) FOR volume IN (' + @ColumnName + ')) AS PVTTable' + +EXEC sp_executesql @DynamicPivotQuery; +` diff --git a/plugins/inputs/sqlserver/sqlserver_test.go b/plugins/inputs/sqlserver/sqlserver_test.go new file mode 100644 index 000000000..1cbe4bd95 --- /dev/null +++ b/plugins/inputs/sqlserver/sqlserver_test.go @@ -0,0 +1,1234 @@ +package sqlserver + +import ( + "strconv" + "strings" + "testing" + "time" + + "github.com/influxdata/telegraf/testutil" + "github.com/stretchr/testify/require" +) + +func TestSqlServer_ParseMetrics(t *testing.T) { + + var acc testutil.Accumulator + + queries = make(MapQuery) + queries["PerformanceCounters"] = Query{Script: mockPerformanceCounters, ResultByRow: true} + queries["WaitStatsCategorized"] = Query{Script: mockWaitStatsCategorized, ResultByRow: false} + queries["CPUHistory"] = Query{Script: mockCPUHistory, ResultByRow: false} + queries["DatabaseIO"] = Query{Script: mockDatabaseIO, ResultByRow: false} + queries["DatabaseSize"] = Query{Script: mockDatabaseSize, ResultByRow: false} + queries["DatabaseStats"] = Query{Script: mockDatabaseStats, ResultByRow: false} + queries["DatabaseProperties"] = Query{Script: mockDatabaseProperties, ResultByRow: false} + queries["VolumeSpace"] = Query{Script: mockVolumeSpace, ResultByRow: false} + queries["MemoryClerk"] = Query{Script: mockMemoryClerk, ResultByRow: false} + queries["PerformanceMetrics"] = Query{Script: mockPerformanceMetrics, ResultByRow: false} + + var headers, mock, row []string + var tags = make(map[string]string) + var fields = make(map[string]interface{}) + + for _, query := range queries { + + mock = strings.Split(query.Script, "\n") + idx := 0 + + for _, line := range mock { + if idx == 0 { // headers in first line + headers = strings.Split(line, ";") + } else { + row = strings.Split(line, ";") + + measurement := row[0] // measurement + tags[headers[1]] = row[1] // tag 'servername' + tags[headers[2]] = row[2] // tag 'type' + + if query.ResultByRow { + + // set value by converting to float64 + value, err := strconv.ParseFloat(row[3], 64) + // require + require.NoError(t, err) + + // add value to Accumulator + acc.Add(measurement, value, tags, time.Now()) + // assert + acc.AssertContainsTaggedFields(t, measurement, map[string]interface{}{"value": value}, tags) + + } else { + // set fields + for i := 3; i < len(row); i++ { + + // set value by converting to float64 + value, err := strconv.ParseFloat(row[i], 64) + // require + require.NoError(t, err) + + fields[headers[i]] = value + } + // add fields to Accumulator + acc.AddFields(measurement, fields, tags, time.Now()) + // assert + acc.AssertContainsTaggedFields(t, measurement, fields, tags) + } + } + idx++ + } + } +} + +const mockPerformanceMetrics = `measurement;servername;type;Point In Time Recovery;Available physical memory (bytes);Average pending disk IO;Average runnable tasks;Average tasks;Buffer pool rate (bytes/sec);Connection memory per connection (bytes);Memory grant pending;Page File Usage (%);Page lookup per batch request;Page split per batch request;Readahead per page read;Signal wait (%);Sql compilation per batch request;Sql recompilation per batch request;Total target memory ratio +Performance metrics;WIN8-DEV;Performance metrics;0;6353158144;0;0;7;2773;415061;0;25;229371;130;10;18;188;52;14` + +const mockWaitStatsCategorized = `measurement;servername;type;I/O;Latch;Lock;Network;Service broker;Memory;Buffer;CLR;XEvent;Other;Total +Wait time (ms);WIN8-DEV;Wait stats;0;0;0;0;0;0;0;0;0;0;0 +Wait tasks;WIN8-DEV;Wait stats;0;0;0;0;0;0;0;0;0;1;1` + +const mockCPUHistory = `measurement;servername;type;SQL process;External process;SystemIdle +CPU (%);WIN8-DEV;CPU;0;2;98` + +const mockDatabaseIO = `measurement;servername;type;AdventureWorks2014;Australian;DOC.Azure;master;model;msdb;ngMon;ResumeCloud;tempdb;Total +Log writes (bytes/sec);WIN8-DEV;Database IO;0;0;0;0;0;0;0;0;159744;159744 +Rows writes (bytes/sec);WIN8-DEV;Database IO;0;0;0;0;0;0;0;0;0;0 +Log reads (bytes/sec);WIN8-DEV;Database IO;0;0;0;0;0;0;0;0;0;0 +Rows reads (bytes/sec);WIN8-DEV;Database IO;0;0;0;0;0;0;0;0;6553;6553 +Log (writes/sec);WIN8-DEV;Database IO;0;0;0;0;0;0;0;0;2;2 +Rows (writes/sec);WIN8-DEV;Database IO;0;0;0;0;0;0;0;0;0;0 +Log (reads/sec);WIN8-DEV;Database IO;0;0;0;0;0;0;0;0;0;0 +Rows (reads/sec);WIN8-DEV;Database IO;0;0;0;0;0;0;0;0;0;0` + +const mockDatabaseSize = `measurement;servername;type;AdventureWorks2014;Australian;DOC.Azure;master;model;msdb;ngMon;ResumeCloud;tempdb +Log size (bytes);WIN8-DEV;Database size;538968064;1048576;786432;2359296;4325376;30212096;1048576;786432;4194304 +Rows size (bytes);WIN8-DEV;Database size;2362703872;3211264;26083328;5111808;3342336;24051712;46137344;10551296;1073741824` + +const mockDatabaseProperties string = `measurement;servername;type;AdventureWorks2014;Australian;DOC.Azure;master;model;msdb;ngMon;ResumeCloud;tempdb;total +Recovery Model FULL;WIN8-DEV;Database properties;1;0;0;0;1;0;0;0;0;2 +Recovery Model BULK_LOGGED;WIN8-DEV;Database properties;0;0;0;0;0;0;0;0;0;0 +Recovery Model SIMPLE;WIN8-DEV;Database properties;0;1;1;1;0;1;1;1;1;7 +State ONLINE;WIN8-DEV;Database properties;1;1;1;1;1;1;1;1;1;9 +State RESTORING;WIN8-DEV;Database properties;0;0;0;0;0;0;0;0;0;0 +State RECOVERING;WIN8-DEV;Database properties;0;0;0;0;0;0;0;0;0;0 +State RECOVERY_PENDING;WIN8-DEV;Database properties;0;0;0;0;0;0;0;0;0;0 +State SUSPECT;WIN8-DEV;Database properties;0;0;0;0;0;0;0;0;0;0 +State EMERGENCY;WIN8-DEV;Database properties;0;0;0;0;0;0;0;0;0;0 +State OFFLINE;WIN8-DEV;Database properties;0;0;0;0;0;0;0;0;0;0` + +const mockMemoryClerk = `measurement;servername;type;Buffer pool;Cache (objects);Cache (sql plans);Other +Memory breakdown (%);WIN8-DEV;Memory clerk;31.30;0.30;14.00;54.50 +Memory breakdown (bytes);WIN8-DEV;Memory clerk;51986432.00;409600.00;23166976.00;90365952.00` + +const mockDatabaseStats = `measurement;servername;type;AdventureWorks2014;Australian;DOC.Azure;master;model;msdb;ngMon;ResumeCloud;tempdb +Log read latency (ms);WIN8-DEV;Database stats;24;20;11;15;20;46;0;0;3 +Log write latency (ms);WIN8-DEV;Database stats;3;0;0;2;0;1;0;0;0 +Rows read latency (ms);WIN8-DEV;Database stats;42;23;52;31;19;29;59;50;71 +Rows write latency (ms);WIN8-DEV;Database stats;0;0;0;9;0;0;0;0;0 +Rows (average bytes/read);WIN8-DEV;Database stats;62580;58056;59603;63015;62968;63042;58056;58919;176703 +Rows (average bytes/write);WIN8-DEV;Database stats;8192;0;0;8192;8192;0;0;0;32768 +Log (average bytes/read);WIN8-DEV;Database stats;69358;50322;74313;41642;19569;29857;45641;18432;143945 +Log (average bytes/write);WIN8-DEV;Database stats;4096;4096;0;5324;4915;4096;4096;32768;52379` + +const mockVolumeSpace = `measurement;servername;type;C:;D: (DATA);L: (LOG) +Volume total space (bytes);WIN8-DEV;OS Volume space;135338651648.00;32075874304.00;10701701120.00 +Volume available space (bytes);WIN8-DEV;OS Volume space;54297817088.00;28439674880.00;10107355136.00 +Volume used space (bytes);WIN8-DEV;OS Volume space;81040834560.00;3636199424.00;594345984.00 +Volume used space (%);WIN8-DEV;OS Volume space;60.00;11.00;6.00` + +const mockPerformanceCounters = `measurement;servername;type;value +AU cleanup batches/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +AU cleanups/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +By-reference Lob Create Count | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +By-reference Lob Use Count | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Count Lob Readahead | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Count Pull In Row | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Count Push Off Row | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Deferred dropped AUs | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Deferred Dropped rowsets | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Dropped rowset cleanups/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Dropped rowsets skipped/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Extent Deallocations/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Extents Allocated/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;2 +Failed AU cleanup batches/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Failed leaf page cookie | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Failed tree page cookie | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Forwarded Records/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +FreeSpace Page Fetches/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +FreeSpace Scans/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Full Scans/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Index Searches/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;1208 +InSysXact waits/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +LobHandle Create Count | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +LobHandle Destroy Count | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +LobSS Provider Create Count | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +LobSS Provider Destroy Count | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +LobSS Provider Truncation Count | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Mixed page allocations/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;10 +Page compression attempts/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Page Deallocations/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Page Splits/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;20 +Pages Allocated/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;22 +Pages compressed/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Probe Scans/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;6 +Range Scans/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;45 +Scan Point Revalidations/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Skipped Ghosted Records/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Table Lock Escalations/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Used leaf page cookie | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Used tree page cookie | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Workfiles Created/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;8 +Worktables Created/sec | SQLServer:Access Methods;WIN8-DEV;Performance counters;2 +Worktables From Cache Base | SQLServer:Access Methods;WIN8-DEV;Performance counters;0 +Worktables From Cache Ratio | SQLServer:Access Methods;WIN8-DEV;Performance counters;1 +Bytes Received from Replica/sec | _Total | SQLServer:Availability Replica;WIN8-DEV;Performance counters;0 +Bytes Sent to Replica/sec | _Total | SQLServer:Availability Replica;WIN8-DEV;Performance counters;0 +Bytes Sent to Transport/sec | _Total | SQLServer:Availability Replica;WIN8-DEV;Performance counters;0 +Flow Control Time (ms/sec) | _Total | SQLServer:Availability Replica;WIN8-DEV;Performance counters;0 +Flow Control/sec | _Total | SQLServer:Availability Replica;WIN8-DEV;Performance counters;0 +Receives from Replica/sec | _Total | SQLServer:Availability Replica;WIN8-DEV;Performance counters;0 +Resent Messages/sec | _Total | SQLServer:Availability Replica;WIN8-DEV;Performance counters;0 +Sends to Replica/sec | _Total | SQLServer:Availability Replica;WIN8-DEV;Performance counters;0 +Sends to Transport/sec | _Total | SQLServer:Availability Replica;WIN8-DEV;Performance counters;0 +Batches >=000000ms & <000001ms | CPU Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;369 +Batches >=000000ms & <000001ms | CPU Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=000000ms & <000001ms | Elapsed Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;370 +Batches >=000000ms & <000001ms | Elapsed Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=000001ms & <000002ms | CPU Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;24 +Batches >=000001ms & <000002ms | CPU Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;24 +Batches >=000001ms & <000002ms | Elapsed Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;16 +Batches >=000001ms & <000002ms | Elapsed Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;16 +Batches >=000002ms & <000005ms | CPU Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;10 +Batches >=000002ms & <000005ms | CPU Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;30 +Batches >=000002ms & <000005ms | Elapsed Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;8 +Batches >=000002ms & <000005ms | Elapsed Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;23 +Batches >=000005ms & <000010ms | CPU Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;30 +Batches >=000005ms & <000010ms | CPU Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;211 +Batches >=000005ms & <000010ms | Elapsed Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;21 +Batches >=000005ms & <000010ms | Elapsed Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;148 +Batches >=000010ms & <000020ms | CPU Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;30 +Batches >=000010ms & <000020ms | CPU Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;432 +Batches >=000010ms & <000020ms | Elapsed Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;21 +Batches >=000010ms & <000020ms | Elapsed Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;305 +Batches >=000020ms & <000050ms | CPU Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;46 +Batches >=000020ms & <000050ms | CPU Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;1545 +Batches >=000020ms & <000050ms | Elapsed Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;37 +Batches >=000020ms & <000050ms | Elapsed Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;1261 +Batches >=000050ms & <000100ms | CPU Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;35 +Batches >=000050ms & <000100ms | CPU Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;2463 +Batches >=000050ms & <000100ms | Elapsed Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;18 +Batches >=000050ms & <000100ms | Elapsed Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;1343 +Batches >=000100ms & <000200ms | CPU Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;1 +Batches >=000100ms & <000200ms | CPU Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;161 +Batches >=000100ms & <000200ms | Elapsed Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;3 +Batches >=000100ms & <000200ms | Elapsed Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;373 +Batches >=000200ms & <000500ms | CPU Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=000200ms & <000500ms | CPU Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=000200ms & <000500ms | Elapsed Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;1 +Batches >=000200ms & <000500ms | Elapsed Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;255 +Batches >=000500ms & <001000ms | CPU Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=000500ms & <001000ms | CPU Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=000500ms & <001000ms | Elapsed Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;2 +Batches >=000500ms & <001000ms | Elapsed Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;1291 +Batches >=001000ms & <002000ms | CPU Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=001000ms & <002000ms | CPU Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=001000ms & <002000ms | Elapsed Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;19 +Batches >=001000ms & <002000ms | Elapsed Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;21560 +Batches >=002000ms & <005000ms | CPU Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=002000ms & <005000ms | CPU Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=002000ms & <005000ms | Elapsed Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;1 +Batches >=002000ms & <005000ms | Elapsed Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;2257 +Batches >=005000ms & <010000ms | CPU Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=005000ms & <010000ms | CPU Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=005000ms & <010000ms | Elapsed Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;19 +Batches >=005000ms & <010000ms | Elapsed Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;97479 +Batches >=010000ms & <020000ms | CPU Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=010000ms & <020000ms | CPU Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=010000ms & <020000ms | Elapsed Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=010000ms & <020000ms | Elapsed Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=020000ms & <050000ms | CPU Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=020000ms & <050000ms | CPU Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=020000ms & <050000ms | Elapsed Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=020000ms & <050000ms | Elapsed Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=050000ms & <100000ms | CPU Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=050000ms & <100000ms | CPU Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=050000ms & <100000ms | Elapsed Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=050000ms & <100000ms | Elapsed Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=100000ms | CPU Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=100000ms | CPU Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=100000ms | Elapsed Time:Requests | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Batches >=100000ms | Elapsed Time:Total(ms) | SQLServer:Batch Resp Statistics;WIN8-DEV;Performance counters;0 +Stored Procedures Invoked/sec | _Total | SQLServer:Broker Activation;WIN8-DEV;Performance counters;0 +Task Limit Reached | _Total | SQLServer:Broker Activation;WIN8-DEV;Performance counters;3 +Task Limit Reached/sec | _Total | SQLServer:Broker Activation;WIN8-DEV;Performance counters;0 +Tasks Aborted/sec | _Total | SQLServer:Broker Activation;WIN8-DEV;Performance counters;0 +Tasks Running | _Total | SQLServer:Broker Activation;WIN8-DEV;Performance counters;0 +Tasks Started/sec | _Total | SQLServer:Broker Activation;WIN8-DEV;Performance counters;0 +Activation Errors Total | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Broker Transaction Rollbacks | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Corrupted Messages Total | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Dequeued TransmissionQ Msgs/sec | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Dialog Timer Event Count | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Dropped Messages Total | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Enqueued Local Messages Total | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Enqueued Local Messages/sec | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Enqueued Messages Total | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Enqueued Messages/sec | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Enqueued P1 Messages/sec | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Enqueued P10 Messages/sec | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Enqueued P2 Messages/sec | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Enqueued P3 Messages/sec | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Enqueued P4 Messages/sec | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Enqueued P5 Messages/sec | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Enqueued P6 Messages/sec | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Enqueued P7 Messages/sec | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Enqueued P8 Messages/sec | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Enqueued P9 Messages/sec | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Enqueued TransmissionQ Msgs/sec | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Enqueued Transport Msg Frag Tot | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Enqueued Transport Msg Frags/sec | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Enqueued Transport Msgs Total | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Enqueued Transport Msgs/sec | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Forwarded Messages Total | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Forwarded Messages/sec | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Forwarded Msg Byte Total | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Forwarded Msg Bytes/sec | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Forwarded Msg Discarded Total | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Forwarded Msgs Discarded/sec | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Forwarded Pending Msg Bytes | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Forwarded Pending Msg Count | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +SQL RECEIVE Total | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +SQL RECEIVEs/sec | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +SQL SEND Total | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +SQL SENDs/sec | SQLServer:Broker Statistics;WIN8-DEV;Performance counters;0 +Avg. Length of Batched Writes | SQLServer:Broker TO Statistics;WIN8-DEV;Performance counters;0 +Avg. Length of Batched Writes BS | SQLServer:Broker TO Statistics;WIN8-DEV;Performance counters;1 +Avg. Time Between Batches (ms) | SQLServer:Broker TO Statistics;WIN8-DEV;Performance counters;2062 +Avg. Time Between Batches Base | SQLServer:Broker TO Statistics;WIN8-DEV;Performance counters;1 +Avg. Time to Write Batch (ms) | SQLServer:Broker TO Statistics;WIN8-DEV;Performance counters;0 +Avg. Time to Write Batch Base | SQLServer:Broker TO Statistics;WIN8-DEV;Performance counters;1 +Transmission Obj Gets/Sec | SQLServer:Broker TO Statistics;WIN8-DEV;Performance counters;0 +Transmission Obj Set Dirty/Sec | SQLServer:Broker TO Statistics;WIN8-DEV;Performance counters;0 +Transmission Obj Writes/Sec | SQLServer:Broker TO Statistics;WIN8-DEV;Performance counters;0 +Current Bytes for Recv I/O | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Current Bytes for Send I/O | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Current Msg Frags for Send I/O | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Message Fragment P1 Sends/sec | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Message Fragment P10 Sends/sec | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Message Fragment P2 Sends/sec | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Message Fragment P3 Sends/sec | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Message Fragment P4 Sends/sec | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Message Fragment P5 Sends/sec | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Message Fragment P6 Sends/sec | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Message Fragment P7 Sends/sec | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Message Fragment P8 Sends/sec | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Message Fragment P9 Sends/sec | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Message Fragment Receives/sec | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Message Fragment Sends/sec | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Msg Fragment Recv Size Avg | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Msg Fragment Recv Size Avg Base | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Msg Fragment Send Size Avg | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Msg Fragment Send Size Avg Base | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Open Connection Count | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Pending Bytes for Recv I/O | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Pending Bytes for Send I/O | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Pending Msg Frags for Recv I/O | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Pending Msg Frags for Send I/O | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Receive I/O bytes/sec | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Receive I/O Len Avg | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Receive I/O Len Avg Base | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Receive I/Os/sec | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Recv I/O Buffer Copies bytes/sec | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Recv I/O Buffer Copies Count | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Send I/O bytes/sec | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Send I/O Len Avg | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Send I/O Len Avg Base | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Send I/Os/sec | SQLServer:Broker/DBM Transport;WIN8-DEV;Performance counters;0 +Background writer pages/sec | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;0 +Buffer cache hit ratio | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;1 +Buffer cache hit ratio base | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;2448 +Checkpoint pages/sec | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;0 +Database pages | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;6676 +Extension allocated pages | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;0 +Extension free pages | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;0 +Extension in use as percentage | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;0 +Extension outstanding IO counter | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;0 +Extension page evictions/sec | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;0 +Extension page reads/sec | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;0 +Extension page unreferenced time | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;0 +Extension page writes/sec | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;0 +Free list stalls/sec | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;0 +Integral Controller Slope | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;10 +Lazy writes/sec | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;0 +Page life expectancy | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;29730 +Page lookups/sec | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;2534 +Page reads/sec | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;0 +Page writes/sec | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;0 +Readahead pages/sec | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;0 +Readahead time/sec | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;0 +Target pages | SQLServer:Buffer Manager;WIN8-DEV;Performance counters;16367616 +Database pages | 000 | SQLServer:Buffer Node;WIN8-DEV;Performance counters;6676 +Local node page lookups/sec | 000 | SQLServer:Buffer Node;WIN8-DEV;Performance counters;0 +Page life expectancy | 000 | SQLServer:Buffer Node;WIN8-DEV;Performance counters;29730 +Remote node page lookups/sec | 000 | SQLServer:Buffer Node;WIN8-DEV;Performance counters;0 +Cache Entries Count | _Total | SQLServer:Catalog Metadata;WIN8-DEV;Performance counters;2428 +Cache Entries Count | mssqlsystemresource | SQLServer:Catalog Metadata;WIN8-DEV;Performance counters;2204 +Cache Entries Pinned Count | _Total | SQLServer:Catalog Metadata;WIN8-DEV;Performance counters;0 +Cache Entries Pinned Count | mssqlsystemresource | SQLServer:Catalog Metadata;WIN8-DEV;Performance counters;0 +Cache Hit Ratio | _Total | SQLServer:Catalog Metadata;WIN8-DEV;Performance counters;1 +Cache Hit Ratio | mssqlsystemresource | SQLServer:Catalog Metadata;WIN8-DEV;Performance counters;1 +Cache Hit Ratio Base | _Total | SQLServer:Catalog Metadata;WIN8-DEV;Performance counters;71 +Cache Hit Ratio Base | mssqlsystemresource | SQLServer:Catalog Metadata;WIN8-DEV;Performance counters;30 +CLR Execution | SQLServer:CLR;WIN8-DEV;Performance counters;327033 +Active cursors | _Total | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Active cursors | API Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Active cursors | TSQL Global Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Active cursors | TSQL Local Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cache Hit Ratio | _Total | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cache Hit Ratio | API Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cache Hit Ratio | TSQL Global Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cache Hit Ratio | TSQL Local Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cache Hit Ratio Base | _Total | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cache Hit Ratio Base | API Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cache Hit Ratio Base | TSQL Global Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cache Hit Ratio Base | TSQL Local Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cached Cursor Counts | _Total | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cached Cursor Counts | API Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cached Cursor Counts | TSQL Global Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cached Cursor Counts | TSQL Local Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cursor Cache Use Counts/sec | _Total | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cursor Cache Use Counts/sec | API Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cursor Cache Use Counts/sec | TSQL Global Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cursor Cache Use Counts/sec | TSQL Local Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cursor memory usage | _Total | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cursor memory usage | API Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cursor memory usage | TSQL Global Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cursor memory usage | TSQL Local Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cursor Requests/sec | _Total | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cursor Requests/sec | API Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cursor Requests/sec | TSQL Global Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cursor Requests/sec | TSQL Local Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cursor worktable usage | _Total | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cursor worktable usage | API Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cursor worktable usage | TSQL Global Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Cursor worktable usage | TSQL Local Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Number of active cursor plans | _Total | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Number of active cursor plans | API Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Number of active cursor plans | TSQL Global Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Number of active cursor plans | TSQL Local Cursor | SQLServer:Cursor Manager by Type;WIN8-DEV;Performance counters;0 +Async population count | SQLServer:Cursor Manager Total;WIN8-DEV;Performance counters;0 +Cursor conversion rate | SQLServer:Cursor Manager Total;WIN8-DEV;Performance counters;0 +Cursor flushes | SQLServer:Cursor Manager Total;WIN8-DEV;Performance counters;0 +File Bytes Received/sec | _Total | SQLServer:Database Replica;WIN8-DEV;Performance counters;0 +Log Bytes Received/sec | _Total | SQLServer:Database Replica;WIN8-DEV;Performance counters;0 +Log remaining for undo | _Total | SQLServer:Database Replica;WIN8-DEV;Performance counters;0 +Log Send Queue | _Total | SQLServer:Database Replica;WIN8-DEV;Performance counters;0 +Mirrored Write Transactions/sec | _Total | SQLServer:Database Replica;WIN8-DEV;Performance counters;0 +Recovery Queue | _Total | SQLServer:Database Replica;WIN8-DEV;Performance counters;0 +Redo blocked/sec | _Total | SQLServer:Database Replica;WIN8-DEV;Performance counters;0 +Redo Bytes Remaining | _Total | SQLServer:Database Replica;WIN8-DEV;Performance counters;0 +Redone Bytes/sec | _Total | SQLServer:Database Replica;WIN8-DEV;Performance counters;0 +Total Log requiring undo | _Total | SQLServer:Database Replica;WIN8-DEV;Performance counters;0 +Transaction Delay | _Total | SQLServer:Database Replica;WIN8-DEV;Performance counters;0 +Active Transactions | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Active Transactions | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Backup/Restore Throughput/sec | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Backup/Restore Throughput/sec | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Bulk Copy Rows/sec | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Bulk Copy Rows/sec | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Bulk Copy Throughput/sec | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Bulk Copy Throughput/sec | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Commit table entries | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Commit table entries | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Data File(s) Size (KB) | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;3512576 +Data File(s) Size (KB) | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;40960 +DBCC Logical Scan Bytes/sec | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +DBCC Logical Scan Bytes/sec | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Group Commit Time/sec | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Group Commit Time/sec | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Bytes Flushed/sec | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;307200 +Log Bytes Flushed/sec | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Cache Hit Ratio | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Cache Hit Ratio | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Cache Hit Ratio Base | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Cache Hit Ratio Base | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Cache Reads/sec | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Cache Reads/sec | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log File(s) Size (KB) | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;570992 +Log File(s) Size (KB) | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;1016 +Log File(s) Used Size (KB) | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;315480 +Log File(s) Used Size (KB) | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;634 +Log Flush Wait Time | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Flush Wait Time | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Flush Waits/sec | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Flush Waits/sec | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Flush Write Time (ms) | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;1 +Log Flush Write Time (ms) | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Flushes/sec | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;5 +Log Flushes/sec | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Growths | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Growths | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Pool Cache Misses/sec | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Pool Cache Misses/sec | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Pool Disk Reads/sec | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Pool Disk Reads/sec | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Pool Requests/sec | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Pool Requests/sec | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Shrinks | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Shrinks | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Log Truncations | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;5 +Log Truncations | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Percent Log Used | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;55 +Percent Log Used | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;62 +Repl. Pending Xacts | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Repl. Pending Xacts | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Repl. Trans. Rate | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Repl. Trans. Rate | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Shrink Data Movement Bytes/sec | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Shrink Data Movement Bytes/sec | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Tracked transactions/sec | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Tracked transactions/sec | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Transactions/sec | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;6 +Transactions/sec | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Write Transactions/sec | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;3 +Write Transactions/sec | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +XTP Memory Used (KB) | _Total | SQLServer:Databases;WIN8-DEV;Performance counters;0 +XTP Memory Used (KB) | mssqlsystemresource | SQLServer:Databases;WIN8-DEV;Performance counters;0 +Usage | '#' and '##' as the name of temporary tables and stored procedures | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | '::' function calling syntax | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | '@' and names that start with '@@' as Transact-SQL identifiers | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | ADDING TAPE DEVICE | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | ALL Permission | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | ALTER DATABASE WITH TORN_PAGE_DETECTION | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | ALTER LOGIN WITH SET CREDENTIAL | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | asymmetric_keys | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | asymmetric_keys.attested_by | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Azeri_Cyrillic_90 | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Azeri_Latin_90 | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | BACKUP DATABASE or LOG TO TAPE | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | certificates | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | certificates.attested_by | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Create/alter SOAP endpoint | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | CREATE_DROP_DEFAULT | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | CREATE_DROP_RULE | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Data types: text ntext or image | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Database compatibility level 100 | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Database compatibility level 110 | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;4 +Usage | Database compatibility level 90 | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Database Mirroring | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | DATABASEPROPERTY | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | DATABASEPROPERTYEX('IsFullTextEnabled') | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | DBCC [UN]PINTABLE | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | DBCC DBREINDEX | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | DBCC INDEXDEFRAG | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | DBCC SHOWCONTIG | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | DBCC_EXTENTINFO | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | DBCC_IND | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | DEFAULT keyword as a default value | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Deprecated Attested Option | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Deprecated encryption algorithm | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | DESX algorithm | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | dm_fts_active_catalogs | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | dm_fts_active_catalogs.is_paused | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | dm_fts_active_catalogs.previous_status | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | dm_fts_active_catalogs.previous_status_description | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | dm_fts_active_catalogs.row_count_in_thousands | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | dm_fts_active_catalogs.status | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | dm_fts_active_catalogs.status_description | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | dm_fts_active_catalogs.worker_count | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | dm_fts_memory_buffers | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | dm_fts_memory_buffers.row_count | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | DROP INDEX with two-part name | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | endpoint_webmethods | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | EXTPROP_LEVEL0TYPE | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | EXTPROP_LEVEL0USER | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | FILE_ID | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | fn_get_sql | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | fn_servershareddrives | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | fn_trace_geteventinfo | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | fn_trace_getfilterinfo | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | fn_trace_getinfo | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | fn_trace_gettable | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | fn_virtualservernodes | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | fulltext_catalogs | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | fulltext_catalogs.data_space_id | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | fulltext_catalogs.file_id | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | fulltext_catalogs.path | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | FULLTEXTCATALOGPROPERTY('LogSize') | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | FULLTEXTCATALOGPROPERTY('PopulateStatus') | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | FULLTEXTSERVICEPROPERTY('ConnectTimeout') | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | FULLTEXTSERVICEPROPERTY('DataTimeout') | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | FULLTEXTSERVICEPROPERTY('ResourceUsage') | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | GROUP BY ALL | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Hindi | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | IDENTITYCOL | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | IN PATH | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Index view select list without COUNT_BIG(*) | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | INDEX_OPTION | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | INDEXKEY_PROPERTY | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Indirect TVF hints | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | INSERT NULL into TIMESTAMP columns | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | INSERT_HINTS | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Korean_Wansung_Unicode | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Lithuanian_Classic | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Macedonian | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | MODIFY FILEGROUP READONLY | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | MODIFY FILEGROUP READWRITE | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | More than two-part column name | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Multiple table hints without comma | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | NOLOCK or READUNCOMMITTED in UPDATE or DELETE | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Numbered stored procedures | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | numbered_procedure_parameters | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | numbered_procedures | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | objidupdate | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Old NEAR Syntax | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | OLEDB for ad hoc connections | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | PERMISSIONS | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | READTEXT | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | REMSERVER | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | RESTORE DATABASE or LOG WITH MEDIAPASSWORD | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | RESTORE DATABASE or LOG WITH PASSWORD | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Returning results from trigger | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | ROWGUIDCOL | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | SET ANSI_NULLS OFF | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | SET ANSI_PADDING OFF | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | SET CONCAT_NULL_YIELDS_NULL OFF | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | SET ERRLVL | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | SET FMTONLY ON | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | SET OFFSETS | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | SET REMOTE_PROC_TRANSACTIONS | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | SET ROWCOUNT | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | SETUSER | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | soap_endpoints | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_addapprole | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_addextendedproc | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_addlogin | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_addremotelogin | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_addrole | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_addrolemember | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_addserver | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_addsrvrolemember | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_addtype | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_adduser | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_approlepassword | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_attach_db | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_attach_single_file_db | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_bindefault | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_bindrule | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_bindsession | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_certify_removable | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_change_users_login | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_changedbowner | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_changeobjectowner | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_configure 'affinity mask' | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_configure 'affinity64 mask' | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_configure 'allow updates' | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_configure 'c2 audit mode' | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_configure 'default trace enabled' | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_configure 'disallow results from triggers' | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_configure 'ft crawl bandwidth (max)' | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_configure 'ft crawl bandwidth (min)' | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_configure 'ft notify bandwidth (max)' | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_configure 'ft notify bandwidth (min)' | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_configure 'locks' | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_configure 'open objects' | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_configure 'priority boost' | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_configure 'remote proc trans' | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_configure 'set working set size' | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_control_dbmasterkey_password | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_create_removable | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_db_increased_partitions | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_db_selective_xml_index | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_db_vardecimal_storage_format | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_dbcmptlevel | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_dbfixedrolepermission | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_dbremove | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_defaultdb | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_defaultlanguage | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_denylogin | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_depends | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_detach_db @keepfulltextindexfile | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_dropapprole | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_dropextendedproc | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_droplogin | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_dropremotelogin | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_droprole | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_droprolemember | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_dropsrvrolemember | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_droptype | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_dropuser | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_estimated_rowsize_reduction_for_vardecimal | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_fulltext_catalog | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_fulltext_column | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_fulltext_database | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_fulltext_service @action=clean_up | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_fulltext_service @action=connect_timeout | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_fulltext_service @action=data_timeout | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_fulltext_service @action=resource_usage | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_fulltext_table | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_getbindtoken | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_grantdbaccess | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_grantlogin | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_help_fulltext_catalog_components | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_help_fulltext_catalogs | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_help_fulltext_catalogs_cursor | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_help_fulltext_columns | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_help_fulltext_columns_cursor | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_help_fulltext_tables | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_help_fulltext_tables_cursor | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_helpdevice | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_helpextendedproc | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_helpremotelogin | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_indexoption | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_lock | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_password | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_remoteoption | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_renamedb | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_resetstatus | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_revokedbaccess | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_revokelogin | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_srvrolepermission | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_trace_create | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_trace_getdata | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_trace_setevent | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_trace_setfilter | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_trace_setstatus | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_unbindefault | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sp_unbindrule | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | SQL_AltDiction_CP1253_CS_AS | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sql_dependencies | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | String literals as column aliases | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysaltfiles | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | syscacheobjects | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | syscolumns | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | syscomments | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysconfigures | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysconstraints | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | syscurconfigs | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysdatabases | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysdepends | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysdevices | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysfilegroups | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysfiles | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysforeignkeys | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysfulltextcatalogs | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysindexes | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysindexkeys | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | syslockinfo | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | syslogins | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysmembers | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysmessages | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysobjects | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysoledbusers | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysopentapes | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysperfinfo | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | syspermissions | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysprocesses | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysprotects | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysreferences | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysremotelogins | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysservers | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | systypes | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | sysusers | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Table hint without WITH | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Text in row table option | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | TEXTPTR | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | TEXTVALID | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | TIMESTAMP | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | UPDATETEXT or WRITETEXT | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | USER_ID | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Using OLEDB for linked servers | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | Vardecimal storage format | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | XMLDATA | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | XP_API | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;3 +Usage | xp_grantlogin | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | xp_loginconfig | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Usage | xp_revokelogin | SQLServer:Deprecated Features;WIN8-DEV;Performance counters;0 +Distributed Query | Average execution time (ms) | SQLServer:Exec Statistics;WIN8-DEV;Performance counters;0 +Distributed Query | Cumulative execution time (ms) per second | SQLServer:Exec Statistics;WIN8-DEV;Performance counters;0 +Distributed Query | Execs in progress | SQLServer:Exec Statistics;WIN8-DEV;Performance counters;0 +Distributed Query | Execs started per second | SQLServer:Exec Statistics;WIN8-DEV;Performance counters;0 +DTC calls | Average execution time (ms) | SQLServer:Exec Statistics;WIN8-DEV;Performance counters;0 +DTC calls | Cumulative execution time (ms) per second | SQLServer:Exec Statistics;WIN8-DEV;Performance counters;0 +DTC calls | Execs in progress | SQLServer:Exec Statistics;WIN8-DEV;Performance counters;0 +DTC calls | Execs started per second | SQLServer:Exec Statistics;WIN8-DEV;Performance counters;0 +Extended Procedures | Average execution time (ms) | SQLServer:Exec Statistics;WIN8-DEV;Performance counters;0 +Extended Procedures | Cumulative execution time (ms) per second | SQLServer:Exec Statistics;WIN8-DEV;Performance counters;0 +Extended Procedures | Execs in progress | SQLServer:Exec Statistics;WIN8-DEV;Performance counters;0 +Extended Procedures | Execs started per second | SQLServer:Exec Statistics;WIN8-DEV;Performance counters;0 +OLEDB calls | Average execution time (ms) | SQLServer:Exec Statistics;WIN8-DEV;Performance counters;0 +OLEDB calls | Cumulative execution time (ms) per second | SQLServer:Exec Statistics;WIN8-DEV;Performance counters;0 +OLEDB calls | Execs in progress | SQLServer:Exec Statistics;WIN8-DEV;Performance counters;0 +OLEDB calls | Execs started per second | SQLServer:Exec Statistics;WIN8-DEV;Performance counters;0 +Avg time delete FileTable item | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +Avg time FileTable enumeration | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +Avg time FileTable handle kill | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +Avg time move FileTable item | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +Avg time per file I/O request | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +Avg time per file I/O response | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +Avg time rename FileTable item | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +Avg time to get FileTable item | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +Avg time update FileTable item | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +FileTable db operations/sec | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +FileTable enumeration reqs/sec | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +FileTable file I/O requests/sec | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +FileTable file I/O response/sec | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +FileTable item delete reqs/sec | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +FileTable item get requests/sec | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +FileTable item move reqs/sec | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +FileTable item rename reqs/sec | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +FileTable item update reqs/sec | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +FileTable kill handle ops/sec | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +FileTable table operations/sec | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +Time delete FileTable item BASE | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +Time FileTable enumeration BASE | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +Time FileTable handle kill BASE | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +Time move FileTable item BASE | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +Time per file I/O request BASE | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +Time per file I/O response BASE | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +Time rename FileTable item BASE | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +Time to get FileTable item BASE | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +Time update FileTable item BASE | SQLServer:FileTable;WIN8-DEV;Performance counters;0 +Active Temp Tables | SQLServer:General Statistics;WIN8-DEV;Performance counters;2 +Connection Reset/sec | SQLServer:General Statistics;WIN8-DEV;Performance counters;0 +Event Notifications Delayed Drop | SQLServer:General Statistics;WIN8-DEV;Performance counters;0 +HTTP Authenticated Requests | SQLServer:General Statistics;WIN8-DEV;Performance counters;0 +Logical Connections | SQLServer:General Statistics;WIN8-DEV;Performance counters;2 +Logins/sec | SQLServer:General Statistics;WIN8-DEV;Performance counters;0 +Logouts/sec | SQLServer:General Statistics;WIN8-DEV;Performance counters;0 +Mars Deadlocks | SQLServer:General Statistics;WIN8-DEV;Performance counters;0 +Non-atomic yield rate | SQLServer:General Statistics;WIN8-DEV;Performance counters;0 +Processes blocked | SQLServer:General Statistics;WIN8-DEV;Performance counters;0 +SOAP Empty Requests | SQLServer:General Statistics;WIN8-DEV;Performance counters;0 +SOAP Method Invocations | SQLServer:General Statistics;WIN8-DEV;Performance counters;0 +SOAP Session Initiate Requests | SQLServer:General Statistics;WIN8-DEV;Performance counters;0 +SOAP Session Terminate Requests | SQLServer:General Statistics;WIN8-DEV;Performance counters;0 +SOAP SQL Requests | SQLServer:General Statistics;WIN8-DEV;Performance counters;0 +SOAP WSDL Requests | SQLServer:General Statistics;WIN8-DEV;Performance counters;0 +SQL Trace IO Provider Lock Waits | SQLServer:General Statistics;WIN8-DEV;Performance counters;0 +Temp Tables Creation Rate | SQLServer:General Statistics;WIN8-DEV;Performance counters;1 +Temp Tables For Destruction | SQLServer:General Statistics;WIN8-DEV;Performance counters;0 +Tempdb recovery unit id | SQLServer:General Statistics;WIN8-DEV;Performance counters;0 +Tempdb rowset id | SQLServer:General Statistics;WIN8-DEV;Performance counters;0 +Trace Event Notification Queue | SQLServer:General Statistics;WIN8-DEV;Performance counters;0 +Transactions | SQLServer:General Statistics;WIN8-DEV;Performance counters;1 +User Connections | SQLServer:General Statistics;WIN8-DEV;Performance counters;2 +Avg. Bytes/Read | _Total | SQLServer:HTTP Storage;WIN8-DEV;Performance counters;0 +Avg. Bytes/Read BASE | _Total | SQLServer:HTTP Storage;WIN8-DEV;Performance counters;0 +Avg. Bytes/Transfer | _Total | SQLServer:HTTP Storage;WIN8-DEV;Performance counters;0 +Avg. Bytes/Transfer BASE | _Total | SQLServer:HTTP Storage;WIN8-DEV;Performance counters;0 +Avg. Bytes/Write | _Total | SQLServer:HTTP Storage;WIN8-DEV;Performance counters;0 +Avg. Bytes/Write BASE | _Total | SQLServer:HTTP Storage;WIN8-DEV;Performance counters;0 +Avg. microsec/Read | _Total | SQLServer:HTTP Storage;WIN8-DEV;Performance counters;0 +Avg. microsec/Read BASE | _Total | SQLServer:HTTP Storage;WIN8-DEV;Performance counters;0 +Avg. microsec/Transfer | _Total | SQLServer:HTTP Storage;WIN8-DEV;Performance counters;0 +Avg. microsec/Transfer BASE | _Total | SQLServer:HTTP Storage;WIN8-DEV;Performance counters;0 +Avg. microsec/Write | _Total | SQLServer:HTTP Storage;WIN8-DEV;Performance counters;0 +Avg. microsec/Write BASE | _Total | SQLServer:HTTP Storage;WIN8-DEV;Performance counters;0 +HTTP Storage IO retry/sec | _Total | SQLServer:HTTP Storage;WIN8-DEV;Performance counters;0 +Outstanding HTTP Storage IO | _Total | SQLServer:HTTP Storage;WIN8-DEV;Performance counters;0 +Read Bytes/Sec | _Total | SQLServer:HTTP Storage;WIN8-DEV;Performance counters;0 +Reads/Sec | _Total | SQLServer:HTTP Storage;WIN8-DEV;Performance counters;0 +Total Bytes/Sec | _Total | SQLServer:HTTP Storage;WIN8-DEV;Performance counters;0 +Transfers/Sec | _Total | SQLServer:HTTP Storage;WIN8-DEV;Performance counters;0 +Write Bytes/Sec | _Total | SQLServer:HTTP Storage;WIN8-DEV;Performance counters;0 +Writes/Sec | _Total | SQLServer:HTTP Storage;WIN8-DEV;Performance counters;0 +Average Latch Wait Time (ms) | SQLServer:Latches;WIN8-DEV;Performance counters;0 +Average Latch Wait Time Base | SQLServer:Latches;WIN8-DEV;Performance counters;0 +Latch Waits/sec | SQLServer:Latches;WIN8-DEV;Performance counters;0 +Number of SuperLatches | SQLServer:Latches;WIN8-DEV;Performance counters;0 +SuperLatch Demotions/sec | SQLServer:Latches;WIN8-DEV;Performance counters;0 +SuperLatch Promotions/sec | SQLServer:Latches;WIN8-DEV;Performance counters;0 +Total Latch Wait Time (ms) | SQLServer:Latches;WIN8-DEV;Performance counters;0 +Average Wait Time (ms) | _Total | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time (ms) | AllocUnit | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time (ms) | Application | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time (ms) | Database | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time (ms) | Extent | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time (ms) | File | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time (ms) | HoBT | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time (ms) | Key | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time (ms) | Metadata | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time (ms) | Object | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time (ms) | OIB | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time (ms) | Page | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time (ms) | RID | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time (ms) | RowGroup | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time Base | _Total | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time Base | AllocUnit | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time Base | Application | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time Base | Database | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time Base | Extent | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time Base | File | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time Base | HoBT | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time Base | Key | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time Base | Metadata | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time Base | Object | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time Base | OIB | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time Base | Page | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time Base | RID | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Average Wait Time Base | RowGroup | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Requests/sec | _Total | SQLServer:Locks;WIN8-DEV;Performance counters;381 +Lock Requests/sec | AllocUnit | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Requests/sec | Application | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Requests/sec | Database | SQLServer:Locks;WIN8-DEV;Performance counters;27 +Lock Requests/sec | Extent | SQLServer:Locks;WIN8-DEV;Performance counters;23 +Lock Requests/sec | File | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Requests/sec | HoBT | SQLServer:Locks;WIN8-DEV;Performance counters;1 +Lock Requests/sec | Key | SQLServer:Locks;WIN8-DEV;Performance counters;133 +Lock Requests/sec | Metadata | SQLServer:Locks;WIN8-DEV;Performance counters;71 +Lock Requests/sec | Object | SQLServer:Locks;WIN8-DEV;Performance counters;93 +Lock Requests/sec | OIB | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Requests/sec | Page | SQLServer:Locks;WIN8-DEV;Performance counters;25 +Lock Requests/sec | RID | SQLServer:Locks;WIN8-DEV;Performance counters;8 +Lock Requests/sec | RowGroup | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts (timeout > 0)/sec | _Total | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts (timeout > 0)/sec | AllocUnit | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts (timeout > 0)/sec | Application | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts (timeout > 0)/sec | Database | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts (timeout > 0)/sec | Extent | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts (timeout > 0)/sec | File | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts (timeout > 0)/sec | HoBT | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts (timeout > 0)/sec | Key | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts (timeout > 0)/sec | Metadata | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts (timeout > 0)/sec | Object | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts (timeout > 0)/sec | OIB | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts (timeout > 0)/sec | Page | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts (timeout > 0)/sec | RID | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts (timeout > 0)/sec | RowGroup | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts/sec | _Total | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts/sec | AllocUnit | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts/sec | Application | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts/sec | Database | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts/sec | Extent | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts/sec | File | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts/sec | HoBT | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts/sec | Key | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts/sec | Metadata | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts/sec | Object | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts/sec | OIB | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts/sec | Page | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts/sec | RID | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Timeouts/sec | RowGroup | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Wait Time (ms) | _Total | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Wait Time (ms) | AllocUnit | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Wait Time (ms) | Application | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Wait Time (ms) | Database | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Wait Time (ms) | Extent | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Wait Time (ms) | File | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Wait Time (ms) | HoBT | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Wait Time (ms) | Key | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Wait Time (ms) | Metadata | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Wait Time (ms) | Object | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Wait Time (ms) | OIB | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Wait Time (ms) | Page | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Wait Time (ms) | RID | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Wait Time (ms) | RowGroup | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Waits/sec | _Total | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Waits/sec | AllocUnit | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Waits/sec | Application | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Waits/sec | Database | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Waits/sec | Extent | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Waits/sec | File | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Waits/sec | HoBT | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Waits/sec | Key | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Waits/sec | Metadata | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Waits/sec | Object | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Waits/sec | OIB | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Waits/sec | Page | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Waits/sec | RID | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Lock Waits/sec | RowGroup | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Number of Deadlocks/sec | _Total | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Number of Deadlocks/sec | AllocUnit | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Number of Deadlocks/sec | Application | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Number of Deadlocks/sec | Database | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Number of Deadlocks/sec | Extent | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Number of Deadlocks/sec | File | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Number of Deadlocks/sec | HoBT | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Number of Deadlocks/sec | Key | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Number of Deadlocks/sec | Metadata | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Number of Deadlocks/sec | Object | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Number of Deadlocks/sec | OIB | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Number of Deadlocks/sec | Page | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Number of Deadlocks/sec | RID | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Number of Deadlocks/sec | RowGroup | SQLServer:Locks;WIN8-DEV;Performance counters;0 +Internal benefit | Buffer Pool | SQLServer:Memory Broker Clerks;WIN8-DEV;Performance counters;0 +Internal benefit | Column store object pool | SQLServer:Memory Broker Clerks;WIN8-DEV;Performance counters;0 +Memory broker clerk size | Buffer Pool | SQLServer:Memory Broker Clerks;WIN8-DEV;Performance counters;6676 +Memory broker clerk size | Column store object pool | SQLServer:Memory Broker Clerks;WIN8-DEV;Performance counters;4 +Periodic evictions (pages) | Buffer Pool | SQLServer:Memory Broker Clerks;WIN8-DEV;Performance counters;0 +Periodic evictions (pages) | Column store object pool | SQLServer:Memory Broker Clerks;WIN8-DEV;Performance counters;0 +Pressure evictions (pages/sec) | Buffer Pool | SQLServer:Memory Broker Clerks;WIN8-DEV;Performance counters;0 +Pressure evictions (pages/sec) | Column store object pool | SQLServer:Memory Broker Clerks;WIN8-DEV;Performance counters;0 +Simulation benefit | Buffer Pool | SQLServer:Memory Broker Clerks;WIN8-DEV;Performance counters;0 +Simulation benefit | Column store object pool | SQLServer:Memory Broker Clerks;WIN8-DEV;Performance counters;0 +Simulation size | Buffer Pool | SQLServer:Memory Broker Clerks;WIN8-DEV;Performance counters;0 +Simulation size | Column store object pool | SQLServer:Memory Broker Clerks;WIN8-DEV;Performance counters;0 +Connection Memory (KB) | SQLServer:Memory Manager;WIN8-DEV;Performance counters;1192 +Database Cache Memory (KB) | SQLServer:Memory Manager;WIN8-DEV;Performance counters;53408 +External benefit of memory | SQLServer:Memory Manager;WIN8-DEV;Performance counters;0 +Free Memory (KB) | SQLServer:Memory Manager;WIN8-DEV;Performance counters;6552 +Granted Workspace Memory (KB) | SQLServer:Memory Manager;WIN8-DEV;Performance counters;0 +Lock Blocks | SQLServer:Memory Manager;WIN8-DEV;Performance counters;0 +Lock Blocks Allocated | SQLServer:Memory Manager;WIN8-DEV;Performance counters;3050 +Lock Memory (KB) | SQLServer:Memory Manager;WIN8-DEV;Performance counters;768 +Lock Owner Blocks | SQLServer:Memory Manager;WIN8-DEV;Performance counters;0 +Lock Owner Blocks Allocated | SQLServer:Memory Manager;WIN8-DEV;Performance counters;5550 +Log Pool Memory (KB) | SQLServer:Memory Manager;WIN8-DEV;Performance counters;1296 +Maximum Workspace Memory (KB) | SQLServer:Memory Manager;WIN8-DEV;Performance counters;1154160 +Memory Grants Outstanding | SQLServer:Memory Manager;WIN8-DEV;Performance counters;0 +Memory Grants Pending | SQLServer:Memory Manager;WIN8-DEV;Performance counters;0 +Optimizer Memory (KB) | SQLServer:Memory Manager;WIN8-DEV;Performance counters;984 +Reserved Server Memory (KB) | SQLServer:Memory Manager;WIN8-DEV;Performance counters;0 +SQL Cache Memory (KB) | SQLServer:Memory Manager;WIN8-DEV;Performance counters;2088 +Stolen Server Memory (KB) | SQLServer:Memory Manager;WIN8-DEV;Performance counters;173608 +Target Server Memory (KB) | SQLServer:Memory Manager;WIN8-DEV;Performance counters;1536000 +Total Server Memory (KB) | SQLServer:Memory Manager;WIN8-DEV;Performance counters;233568 +Database Node Memory (KB) | 000 | SQLServer:Memory Node;WIN8-DEV;Performance counters;53408 +Foreign Node Memory (KB) | 000 | SQLServer:Memory Node;WIN8-DEV;Performance counters;0 +Free Node Memory (KB) | 000 | SQLServer:Memory Node;WIN8-DEV;Performance counters;6552 +Stolen Node Memory (KB) | 000 | SQLServer:Memory Node;WIN8-DEV;Performance counters;173592 +Target Node Memory (KB) | 000 | SQLServer:Memory Node;WIN8-DEV;Performance counters;1535976 +Total Node Memory (KB) | 000 | SQLServer:Memory Node;WIN8-DEV;Performance counters;233552 +Cache Hit Ratio | _Total | SQLServer:Plan Cache;WIN8-DEV;Performance counters;1 +Cache Hit Ratio | Bound Trees | SQLServer:Plan Cache;WIN8-DEV;Performance counters;1 +Cache Hit Ratio | Extended Stored Procedures | SQLServer:Plan Cache;WIN8-DEV;Performance counters;1 +Cache Hit Ratio | Object Plans | SQLServer:Plan Cache;WIN8-DEV;Performance counters;0 +Cache Hit Ratio | SQL Plans | SQLServer:Plan Cache;WIN8-DEV;Performance counters;1 +Cache Hit Ratio | Temporary Tables & Table Variables | SQLServer:Plan Cache;WIN8-DEV;Performance counters;0 +Cache Hit Ratio Base | _Total | SQLServer:Plan Cache;WIN8-DEV;Performance counters;6 +Cache Hit Ratio Base | Bound Trees | SQLServer:Plan Cache;WIN8-DEV;Performance counters;6 +Cache Hit Ratio Base | Extended Stored Procedures | SQLServer:Plan Cache;WIN8-DEV;Performance counters;0 +Cache Hit Ratio Base | Object Plans | SQLServer:Plan Cache;WIN8-DEV;Performance counters;0 +Cache Hit Ratio Base | SQL Plans | SQLServer:Plan Cache;WIN8-DEV;Performance counters;0 +Cache Hit Ratio Base | Temporary Tables & Table Variables | SQLServer:Plan Cache;WIN8-DEV;Performance counters;0 +Cache Object Counts | _Total | SQLServer:Plan Cache;WIN8-DEV;Performance counters;230 +Cache Object Counts | Bound Trees | SQLServer:Plan Cache;WIN8-DEV;Performance counters;90 +Cache Object Counts | Extended Stored Procedures | SQLServer:Plan Cache;WIN8-DEV;Performance counters;4 +Cache Object Counts | Object Plans | SQLServer:Plan Cache;WIN8-DEV;Performance counters;2 +Cache Object Counts | SQL Plans | SQLServer:Plan Cache;WIN8-DEV;Performance counters;134 +Cache Object Counts | Temporary Tables & Table Variables | SQLServer:Plan Cache;WIN8-DEV;Performance counters;0 +Cache Objects in use | _Total | SQLServer:Plan Cache;WIN8-DEV;Performance counters;1 +Cache Objects in use | Bound Trees | SQLServer:Plan Cache;WIN8-DEV;Performance counters;0 +Cache Objects in use | Extended Stored Procedures | SQLServer:Plan Cache;WIN8-DEV;Performance counters;0 +Cache Objects in use | Object Plans | SQLServer:Plan Cache;WIN8-DEV;Performance counters;0 +Cache Objects in use | SQL Plans | SQLServer:Plan Cache;WIN8-DEV;Performance counters;1 +Cache Objects in use | Temporary Tables & Table Variables | SQLServer:Plan Cache;WIN8-DEV;Performance counters;0 +Cache Pages | _Total | SQLServer:Plan Cache;WIN8-DEV;Performance counters;5759 +Cache Pages | Bound Trees | SQLServer:Plan Cache;WIN8-DEV;Performance counters;1055 +Cache Pages | Extended Stored Procedures | SQLServer:Plan Cache;WIN8-DEV;Performance counters;6 +Cache Pages | Object Plans | SQLServer:Plan Cache;WIN8-DEV;Performance counters;50 +Cache Pages | SQL Plans | SQLServer:Plan Cache;WIN8-DEV;Performance counters;4646 +Cache Pages | Temporary Tables & Table Variables | SQLServer:Plan Cache;WIN8-DEV;Performance counters;2 +Active memory grant amount (KB) | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Active memory grant amount (KB) | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Active memory grants count | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Active memory grants count | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Avg Disk Read IO (ms) | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Avg Disk Read IO (ms) | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Avg Disk Read IO (ms) Base | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Avg Disk Read IO (ms) Base | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Avg Disk Write IO (ms) | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Avg Disk Write IO (ms) | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Avg Disk Write IO (ms) Base | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Avg Disk Write IO (ms) Base | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Cache memory target (KB) | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;1231200 +Cache memory target (KB) | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;1231200 +Compile memory target (KB) | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;1231200 +Compile memory target (KB) | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;1231200 +CPU control effect % | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;7 +CPU control effect % | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +CPU usage % | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +CPU usage % | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +CPU usage % base | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +CPU usage % base | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +CPU usage target % | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;7 +CPU usage target % | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Disk Read Bytes/sec | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Disk Read Bytes/sec | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Disk Read IO Throttled/sec | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Disk Read IO Throttled/sec | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Disk Read IO/sec | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Disk Read IO/sec | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Disk Write Bytes/sec | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Disk Write Bytes/sec | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Disk Write IO Throttled/sec | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Disk Write IO Throttled/sec | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Disk Write IO/sec | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Disk Write IO/sec | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Max memory (KB) | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;1459200 +Max memory (KB) | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;1459200 +Memory grant timeouts/sec | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Memory grant timeouts/sec | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Memory grants/sec | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;1 +Memory grants/sec | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Pending memory grants count | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Pending memory grants count | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;0 +Query exec memory target (KB) | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;1154160 +Query exec memory target (KB) | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;1154160 +Target memory (KB) | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;1459200 +Target memory (KB) | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;1459200 +Used memory (KB) | default | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;52624 +Used memory (KB) | internal | SQLServer:Resource Pool Stats;WIN8-DEV;Performance counters;120976 +Errors/sec | _Total | SQLServer:SQL Errors;WIN8-DEV;Performance counters;0 +Errors/sec | DB Offline Errors | SQLServer:SQL Errors;WIN8-DEV;Performance counters;0 +Errors/sec | Info Errors | SQLServer:SQL Errors;WIN8-DEV;Performance counters;0 +Errors/sec | Kill Connection Errors | SQLServer:SQL Errors;WIN8-DEV;Performance counters;0 +Errors/sec | User Errors | SQLServer:SQL Errors;WIN8-DEV;Performance counters;0 +Auto-Param Attempts/sec | SQLServer:SQL Statistics;WIN8-DEV;Performance counters;0 +Batch Requests/sec | SQLServer:SQL Statistics;WIN8-DEV;Performance counters;0 +Failed Auto-Params/sec | SQLServer:SQL Statistics;WIN8-DEV;Performance counters;0 +Forced Parameterizations/sec | SQLServer:SQL Statistics;WIN8-DEV;Performance counters;0 +Guided plan executions/sec | SQLServer:SQL Statistics;WIN8-DEV;Performance counters;0 +Misguided plan executions/sec | SQLServer:SQL Statistics;WIN8-DEV;Performance counters;0 +Safe Auto-Params/sec | SQLServer:SQL Statistics;WIN8-DEV;Performance counters;0 +SQL Attention rate | SQLServer:SQL Statistics;WIN8-DEV;Performance counters;0 +SQL Compilations/sec | SQLServer:SQL Statistics;WIN8-DEV;Performance counters;1 +SQL Re-Compilations/sec | SQLServer:SQL Statistics;WIN8-DEV;Performance counters;1 +Unsafe Auto-Params/sec | SQLServer:SQL Statistics;WIN8-DEV;Performance counters;0 +Free Space in tempdb (KB) | SQLServer:Transactions;WIN8-DEV;Performance counters;1045504 +Longest Transaction Running Time | SQLServer:Transactions;WIN8-DEV;Performance counters;0 +NonSnapshot Version Transactions | SQLServer:Transactions;WIN8-DEV;Performance counters;0 +Snapshot Transactions | SQLServer:Transactions;WIN8-DEV;Performance counters;0 +Transactions | SQLServer:Transactions;WIN8-DEV;Performance counters;14 +Update conflict ratio | SQLServer:Transactions;WIN8-DEV;Performance counters;0 +Update conflict ratio base | SQLServer:Transactions;WIN8-DEV;Performance counters;0 +Update Snapshot Transactions | SQLServer:Transactions;WIN8-DEV;Performance counters;0 +Version Cleanup rate (KB/s) | SQLServer:Transactions;WIN8-DEV;Performance counters;0 +Version Generation rate (KB/s) | SQLServer:Transactions;WIN8-DEV;Performance counters;0 +Version Store Size (KB) | SQLServer:Transactions;WIN8-DEV;Performance counters;0 +Version Store unit count | SQLServer:Transactions;WIN8-DEV;Performance counters;2 +Version Store unit creation | SQLServer:Transactions;WIN8-DEV;Performance counters;2 +Version Store unit truncation | SQLServer:Transactions;WIN8-DEV;Performance counters;0 +Query | User counter 1 | SQLServer:User Settable;WIN8-DEV;Performance counters;0 +Query | User counter 10 | SQLServer:User Settable;WIN8-DEV;Performance counters;0 +Query | User counter 2 | SQLServer:User Settable;WIN8-DEV;Performance counters;0 +Query | User counter 3 | SQLServer:User Settable;WIN8-DEV;Performance counters;0 +Query | User counter 4 | SQLServer:User Settable;WIN8-DEV;Performance counters;0 +Query | User counter 5 | SQLServer:User Settable;WIN8-DEV;Performance counters;0 +Query | User counter 6 | SQLServer:User Settable;WIN8-DEV;Performance counters;0 +Query | User counter 7 | SQLServer:User Settable;WIN8-DEV;Performance counters;0 +Query | User counter 8 | SQLServer:User Settable;WIN8-DEV;Performance counters;0 +Query | User counter 9 | SQLServer:User Settable;WIN8-DEV;Performance counters;0 +Lock waits | Average wait time (ms) | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Lock waits | Cumulative wait time (ms) per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Lock waits | Waits in progress | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Lock waits | Waits started per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Log buffer waits | Average wait time (ms) | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Log buffer waits | Cumulative wait time (ms) per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Log buffer waits | Waits in progress | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Log buffer waits | Waits started per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Log write waits | Average wait time (ms) | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Log write waits | Cumulative wait time (ms) per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Log write waits | Waits in progress | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Log write waits | Waits started per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Memory grant queue waits | Average wait time (ms) | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Memory grant queue waits | Cumulative wait time (ms) per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Memory grant queue waits | Waits in progress | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Memory grant queue waits | Waits started per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Network IO waits | Average wait time (ms) | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Network IO waits | Cumulative wait time (ms) per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Network IO waits | Waits in progress | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Network IO waits | Waits started per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Non-Page latch waits | Average wait time (ms) | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Non-Page latch waits | Cumulative wait time (ms) per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Non-Page latch waits | Waits in progress | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Non-Page latch waits | Waits started per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Page IO latch waits | Average wait time (ms) | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Page IO latch waits | Cumulative wait time (ms) per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Page IO latch waits | Waits in progress | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Page IO latch waits | Waits started per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Page latch waits | Average wait time (ms) | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Page latch waits | Cumulative wait time (ms) per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Page latch waits | Waits in progress | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Page latch waits | Waits started per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Thread-safe memory objects waits | Average wait time (ms) | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Thread-safe memory objects waits | Cumulative wait time (ms) per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Thread-safe memory objects waits | Waits in progress | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Thread-safe memory objects waits | Waits started per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Transaction ownership waits | Average wait time (ms) | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Transaction ownership waits | Cumulative wait time (ms) per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Transaction ownership waits | Waits in progress | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Transaction ownership waits | Waits started per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Wait for the worker | Average wait time (ms) | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Wait for the worker | Cumulative wait time (ms) per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Wait for the worker | Waits in progress | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Wait for the worker | Waits started per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Workspace synchronization waits | Average wait time (ms) | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Workspace synchronization waits | Cumulative wait time (ms) per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Workspace synchronization waits | Waits in progress | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Workspace synchronization waits | Waits started per second | SQLServer:Wait Statistics;WIN8-DEV;Performance counters;0 +Active parallel threads | default | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;0 +Active parallel threads | internal | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;0 +Active requests | default | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;1 +Active requests | internal | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;0 +Blocked tasks | default | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;0 +Blocked tasks | internal | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;0 +CPU usage % | default | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;0 +CPU usage % | internal | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;0 +CPU usage % base | default | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;0 +CPU usage % base | internal | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;0 +Max request cpu time (ms) | default | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;161 +Max request cpu time (ms) | internal | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;0 +Max request memory grant (KB) | default | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;9816 +Max request memory grant (KB) | internal | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;0 +Query optimizations/sec | default | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;1 +Query optimizations/sec | internal | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;0 +Queued requests | default | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;0 +Queued requests | internal | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;0 +Reduced memory grants/sec | default | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;0 +Reduced memory grants/sec | internal | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;0 +Requests completed/sec | default | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;0 +Requests completed/sec | internal | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;0 +Suboptimal plans/sec | default | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;0 +Suboptimal plans/sec | internal | SQLServer:Workload Group Stats;WIN8-DEV;Performance counters;0 +Cursor deletes/sec | MSSQLSERVER | XTP Cursors;WIN8-DEV;Performance counters;0 +Cursor inserts/sec | MSSQLSERVER | XTP Cursors;WIN8-DEV;Performance counters;0 +Cursor scans started/sec | MSSQLSERVER | XTP Cursors;WIN8-DEV;Performance counters;0 +Cursor unique violations/sec | MSSQLSERVER | XTP Cursors;WIN8-DEV;Performance counters;0 +Cursor updates/sec | MSSQLSERVER | XTP Cursors;WIN8-DEV;Performance counters;0 +Cursor write conflicts/sec | MSSQLSERVER | XTP Cursors;WIN8-DEV;Performance counters;0 +Dusty corner scan retries/sec (user-issued) | MSSQLSERVER | XTP Cursors;WIN8-DEV;Performance counters;0 +Expired rows removed/sec | MSSQLSERVER | XTP Cursors;WIN8-DEV;Performance counters;0 +Expired rows touched/sec | MSSQLSERVER | XTP Cursors;WIN8-DEV;Performance counters;0 +Rows returned/sec | MSSQLSERVER | XTP Cursors;WIN8-DEV;Performance counters;0 +Rows touched/sec | MSSQLSERVER | XTP Cursors;WIN8-DEV;Performance counters;0 +Tentatively-deleted rows touched/sec | MSSQLSERVER | XTP Cursors;WIN8-DEV;Performance counters;0 +Dusty corner scan retries/sec (GC-issued) | MSSQLSERVER | XTP Garbage Collection;WIN8-DEV;Performance counters;0 +Main GC work items/sec | MSSQLSERVER | XTP Garbage Collection;WIN8-DEV;Performance counters;0 +Parallel GC work item/sec | MSSQLSERVER | XTP Garbage Collection;WIN8-DEV;Performance counters;0 +Rows processed/sec | MSSQLSERVER | XTP Garbage Collection;WIN8-DEV;Performance counters;0 +Rows processed/sec (first in bucket and removed) | MSSQLSERVER | XTP Garbage Collection;WIN8-DEV;Performance counters;0 +Rows processed/sec (first in bucket) | MSSQLSERVER | XTP Garbage Collection;WIN8-DEV;Performance counters;0 +Rows processed/sec (marked for unlink) | MSSQLSERVER | XTP Garbage Collection;WIN8-DEV;Performance counters;0 +Rows processed/sec (no sweep needed) | MSSQLSERVER | XTP Garbage Collection;WIN8-DEV;Performance counters;0 +Sweep expired rows removed/sec | MSSQLSERVER | XTP Garbage Collection;WIN8-DEV;Performance counters;0 +Sweep expired rows touched/sec | MSSQLSERVER | XTP Garbage Collection;WIN8-DEV;Performance counters;0 +Sweep expiring rows touched/sec | MSSQLSERVER | XTP Garbage Collection;WIN8-DEV;Performance counters;0 +Sweep rows touched/sec | MSSQLSERVER | XTP Garbage Collection;WIN8-DEV;Performance counters;0 +Sweep scans started/sec | MSSQLSERVER | XTP Garbage Collection;WIN8-DEV;Performance counters;0 +Dusty corner scan retries/sec (Phantom-issued) | MSSQLSERVER | XTP Phantom Processor;WIN8-DEV;Performance counters;0 +Phantom expired rows removed/sec | MSSQLSERVER | XTP Phantom Processor;WIN8-DEV;Performance counters;0 +Phantom expired rows touched/sec | MSSQLSERVER | XTP Phantom Processor;WIN8-DEV;Performance counters;0 +Phantom expiring rows touched/sec | MSSQLSERVER | XTP Phantom Processor;WIN8-DEV;Performance counters;0 +Phantom rows touched/sec | MSSQLSERVER | XTP Phantom Processor;WIN8-DEV;Performance counters;0 +Phantom scans started/sec | MSSQLSERVER | XTP Phantom Processor;WIN8-DEV;Performance counters;0 +Checkpoints Closed | MSSQLSERVER | XTP Storage;WIN8-DEV;Performance counters;0 +Checkpoints Completed | MSSQLSERVER | XTP Storage;WIN8-DEV;Performance counters;0 +Core Merges Completed | MSSQLSERVER | XTP Storage;WIN8-DEV;Performance counters;0 +Merge Policy Evaluations | MSSQLSERVER | XTP Storage;WIN8-DEV;Performance counters;0 +Merge Requests Outstanding | MSSQLSERVER | XTP Storage;WIN8-DEV;Performance counters;0 +Merges Abandoned | MSSQLSERVER | XTP Storage;WIN8-DEV;Performance counters;0 +Merges Installed | MSSQLSERVER | XTP Storage;WIN8-DEV;Performance counters;0 +Total Files Merged | MSSQLSERVER | XTP Storage;WIN8-DEV;Performance counters;0 +Log bytes written/sec | MSSQLSERVER | XTP Transaction Log;WIN8-DEV;Performance counters;0 +Log records written/sec | MSSQLSERVER | XTP Transaction Log;WIN8-DEV;Performance counters;0 +Cascading aborts/sec | MSSQLSERVER | XTP Transactions;WIN8-DEV;Performance counters;0 +Commit dependencies taken/sec | MSSQLSERVER | XTP Transactions;WIN8-DEV;Performance counters;0 +Read-only transactions prepared/sec | MSSQLSERVER | XTP Transactions;WIN8-DEV;Performance counters;0 +Save point refreshes/sec | MSSQLSERVER | XTP Transactions;WIN8-DEV;Performance counters;0 +Save point rollbacks/sec | MSSQLSERVER | XTP Transactions;WIN8-DEV;Performance counters;0 +Save points created/sec | MSSQLSERVER | XTP Transactions;WIN8-DEV;Performance counters;0 +Transaction validation failures/sec | MSSQLSERVER | XTP Transactions;WIN8-DEV;Performance counters;0 +Transactions aborted by user/sec | MSSQLSERVER | XTP Transactions;WIN8-DEV;Performance counters;0 +Transactions aborted/sec | MSSQLSERVER | XTP Transactions;WIN8-DEV;Performance counters;0 +Transactions created/sec | MSSQLSERVER | XTP Transactions;WIN8-DEV;Performance counters;0` diff --git a/plugins/inputs/system/DISK_README.md b/plugins/inputs/system/DISK_README.md new file mode 100644 index 000000000..c89007b45 --- /dev/null +++ b/plugins/inputs/system/DISK_README.md @@ -0,0 +1,45 @@ +# Disk Input Plugin + +The disk input plugin gathers metrics about disk usage. + +Note that `used_percent` is calculated by doing `used / (used + free)`, _not_ +`used / total`, which is how the unix `df` command does it. See +https://en.wikipedia.org/wiki/Df_(Unix) for more details. + +### Configuration: + +``` +# Read metrics about disk usage by mount point +[[inputs.disk]] + # By default, telegraf gather stats for all mountpoints. + # Setting mountpoints will restrict the stats to the specified mountpoints. + # mount_points = ["/"] +``` + +### Measurements & Fields: + +- disk + - free (integer, bytes) + - total (integer, bytes) + - used (integer, bytes) + - used_percent (float, percent) + - inodes_free (integer, files) + - inodes_total (integer, files) + - inodes_used (integer, files) + +### Tags: + +- All measurements have the following tags: + - fstype (filesystem type) + - path (mount point path) + +### Example Output: + +``` +% ./telegraf -config ~/ws/telegraf.conf -input-filter disk -test +* Plugin: disk, Collection 1 +> disk,fstype=hfs,path=/ free=398407520256i,inodes_free=97267461i,inodes_total=121847806i,inodes_used=24580345i,total=499088621568i,used=100418957312i,used_percent=20.131039916242397 1453832006274071563 +> disk,fstype=devfs,path=/dev free=0i,inodes_free=0i,inodes_total=628i,inodes_used=628i,total=185856i,used=185856i,used_percent=100 1453832006274137913 +> disk,fstype=autofs,path=/net free=0i,inodes_free=0i,inodes_total=0i,inodes_used=0i,total=0i,used=0i,used_percent=0 1453832006274157077 +> disk,fstype=autofs,path=/home free=0i,inodes_free=0i,inodes_total=0i,inodes_used=0i,total=0i,used=0i,used_percent=0 1453832006274169688 +``` diff --git a/plugins/inputs/system/disk.go b/plugins/inputs/system/disk.go index c6b23492b..5143859d1 100644 --- a/plugins/inputs/system/disk.go +++ b/plugins/inputs/system/disk.go @@ -45,13 +45,20 @@ func (s *DiskStats) Gather(acc inputs.Accumulator) error { "path": du.Path, "fstype": du.Fstype, } + var used_percent float64 + if du.Used+du.Free > 0 { + used_percent = float64(du.Used) / + (float64(du.Used) + float64(du.Free)) * 100 + } + fields := map[string]interface{}{ "total": du.Total, "free": du.Free, - "used": du.Total - du.Free, + "used": du.Used, + "used_percent": used_percent, "inodes_total": du.InodesTotal, "inodes_free": du.InodesFree, - "inodes_used": du.InodesTotal - du.InodesFree, + "inodes_used": du.InodesUsed, } acc.AddFields("disk", fields, tags) } diff --git a/plugins/inputs/system/disk_test.go b/plugins/inputs/system/disk_test.go index ec4182cb3..8a31957c0 100644 --- a/plugins/inputs/system/disk_test.go +++ b/plugins/inputs/system/disk_test.go @@ -21,16 +21,20 @@ func TestDiskStats(t *testing.T) { Fstype: "ext4", Total: 128, Free: 23, + Used: 100, InodesTotal: 1234, InodesFree: 234, + InodesUsed: 1000, }, { Path: "/home", Fstype: "ext4", Total: 256, Free: 46, + Used: 200, InodesTotal: 2468, InodesFree: 468, + InodesUsed: 2000, }, } duFiltered := []*disk.DiskUsageStat{ @@ -39,8 +43,10 @@ func TestDiskStats(t *testing.T) { Fstype: "ext4", Total: 128, Free: 23, + Used: 100, InodesTotal: 1234, InodesFree: 234, + InodesUsed: 1000, }, } @@ -52,7 +58,7 @@ func TestDiskStats(t *testing.T) { require.NoError(t, err) numDiskPoints := acc.NFields() - expectedAllDiskPoints := 12 + expectedAllDiskPoints := 14 assert.Equal(t, expectedAllDiskPoints, numDiskPoints) tags1 := map[string]string{ @@ -66,19 +72,21 @@ func TestDiskStats(t *testing.T) { fields1 := map[string]interface{}{ "total": uint64(128), - "used": uint64(105), + "used": uint64(100), "free": uint64(23), "inodes_total": uint64(1234), "inodes_free": uint64(234), "inodes_used": uint64(1000), + "used_percent": float64(81.30081300813008), } fields2 := map[string]interface{}{ "total": uint64(256), - "used": uint64(210), + "used": uint64(200), "free": uint64(46), "inodes_total": uint64(2468), "inodes_free": uint64(468), "inodes_used": uint64(2000), + "used_percent": float64(81.30081300813008), } acc.AssertContainsTaggedFields(t, "disk", fields1, tags1) acc.AssertContainsTaggedFields(t, "disk", fields2, tags2) @@ -86,12 +94,12 @@ func TestDiskStats(t *testing.T) { // We expect 6 more DiskPoints to show up with an explicit match on "/" // and /home not matching the /dev in MountPoints err = (&DiskStats{ps: &mps, MountPoints: []string{"/", "/dev"}}).Gather(&acc) - assert.Equal(t, expectedAllDiskPoints+6, acc.NFields()) + assert.Equal(t, expectedAllDiskPoints+7, acc.NFields()) // We should see all the diskpoints as MountPoints includes both // / and /home err = (&DiskStats{ps: &mps, MountPoints: []string{"/", "/home"}}).Gather(&acc) - assert.Equal(t, 2*expectedAllDiskPoints+6, acc.NFields()) + assert.Equal(t, 2*expectedAllDiskPoints+7, acc.NFields()) } // func TestDiskIOStats(t *testing.T) { diff --git a/plugins/outputs/kinesis/kinesis.go b/plugins/outputs/kinesis/kinesis.go index f04f1c7c6..23ca03c5e 100644 --- a/plugins/outputs/kinesis/kinesis.go +++ b/plugins/outputs/kinesis/kinesis.go @@ -1,7 +1,6 @@ package kinesis import ( - "errors" "fmt" "log" "os" @@ -101,7 +100,7 @@ func (k *KinesisOutput) Connect() error { } func (k *KinesisOutput) Close() error { - return errors.New("Error") + return nil } func FormatMetric(k *KinesisOutput, point *client.Point) (string, error) { diff --git a/scripts/post-install.sh b/scripts/post-install.sh index bb4803f8d..4f11fe8f6 100644 --- a/scripts/post-install.sh +++ b/scripts/post-install.sh @@ -66,4 +66,11 @@ elif [[ -f /etc/debian_version ]]; then install_init install_update_rcd fi +elif [[ -f /etc/os-release ]]; then + source /etc/os-release + if [[ $ID = "amzn" ]]; then + # Amazon Linux logic + install_init + install_chkconfig + fi fi