Code Monkey home page Code Monkey logo

pingpong's Introduction

Pingpong Logo

Pingpong Build Status

Deploy

Get deeper HTTP request response analytics every second.

Track real-time performance and availability across multiple API servers to see the what, when, and how behind your system performance. So you can understand why.

Pingpong Graph

How does it work?

  • Pingpong sends HTTP requests to URLs you configure as frequently as once per second. It turns data about each request and response into JSON, then logs it to a custom destination.
  • Your default data store is Keen IO’s analytics API to capture events, run queries, and create visualizations. But it’s simple to set up another backend.
  • Pingpong ships with Dashboards, an HTML visualization kit that lets you see and arrange your most critical response data. Built on the Keen IO analytics API, Dashboards is super-flexible and ready to be skinned, tweaked, and embedded anywhere.
  • Pingpong captures most of the data you'd want about HTTP requests and responses. To beef up or slim down your data stream, adding custom properties specific to your infrastructure is simple.

Choose your own install adventure.

Deploy straight to Heroku: Pingpong is easy to install and ready for deployment to one or more Heroku regions. You can even deploy the app with a single click with this handy button:

Deploy

A note on event limits: If you're using the Keen IO backend to store events, you can send 50,000 events for free per month. As a reference, one check running every minute will create about 43,000 events in a month. Check out more plans to get more events. We'd also love to give you a discount if you're using Pingpong, just [email us](mailto:[email protected]?subject=Pingpong Events) your project ID and we'll get you hooked up.

Setup and deploy your own Pingpong app: Don't run Heroku? That's cool. You can run Pingpong on any host with Ruby, even your local machine. Either way, it's up and running in less than five minutes. Just see the next section.

Setup & Deployment

Pingpong is open source and easy to install. Pingpong is written in Ruby and streamlined for deployment to one or more Heroku regions. That said, you can run it on any host with Ruby, including your local machine.

Step 1: Clone or fork this repository:

$ git clone [email protected]:keen/pingpong.git
$ cd pingpong

Step 2: Install dependencies

$ bundle install

If you don't have the bundle command, first gem install bundler.

Step 3: Set up database tables

$ bundle exec rake db:create
$ bundle exec rake db:migrate

The project uses Postgres as the default database, but you can modify that in the database.yml file.

Step 4: Set up the environment variables

Keen IO Setup

You'll need to sign up for a free Keen IO account. Once your account is set up, create a new project.

You'll need to grab the project id, read key, and write key. Add these to a root level file called .env. There's a .env.sample setup with all the variables, so just run:

$ cp .env.sample .env

And edit your Keen IO variables:

KEEN_PROJECT_ID=xxxxxxxxxxxxxxx
KEEN_READ_KEY=yyyyyyyyyyyyyyyyy
KEEN_WRITE_KEY=zzzzzzzzzzzzzzzz

SendGrid Setup

If you want to send emails, you'll have to sign up for a free SendGrid account.

Once you've done that, edit the following in your .env file:

[email protected]
[email protected]
SKIP_EMAIL=false
SENDGRID_USERNAME=asdfasdfasdf
SENDGRID_PASSWORD=12345

Slack Setup

To get notifications in Slack, you'll have to provide us with your Incoming Webhook URL. You can create an Incoming Webhook here.

Once you've got the Webhook URL, update your .env file:

SLACK_WEBHOOK_URL=https://hooks.slack.com/services/XXXXXXXXXXXXXXX/YYYYYYYYYYY

There are also some optional configurations you can edit for Slack notifications:

SLACK_CHANNEL='#alerts' # The channel to send notifications to
SLACK_USERNAME='Robot' # The username the notification will come from - defaults to Pingpong
SLACK_ICON=':rotating_light' # The icon of the user "sending" the notification. Can be a URL or an Emoji
WARN_COLOR='#CCCCCC' # Hex color value used for the warning messages - defaults to #E2E541
BAD_COLOR='#000000' # Hex color value used for the failure messages - defaults to #F25656

Run the Server

Now you're ready to start the web server locally using foreman, which will pick up the variables in the .env file. foreman comes with the Heroku toolbelt.

$ foreman start

The Pingpong web interface should now be running on localhost:5000. Click on the button to create a new check, and then within a few minutes, you'll see the check data populating the charts.

Check Properties

Every check requires the following properties:

  • name: for display in charts and reports
  • url: the fully qualified resource to check
  • frequency: how often to sent the request, in minutes

Additionally, checks have some optional properties:

  • method: GET, POST, or DELETE (defaults to GET)
  • http_username: Username for HTTP authentication
  • http_password: Password for HTTP authentication

Checks can also have any number of custom properties, which is very useful for grouping & drill-down analysis later. Place any custom properties in the custom field.

HTTP Request & Response as an Event

Each time a check is run, a JSON object describing the check, request, and response is logged via a CheckLogger component, defaulting to KeenCheckLogger. Here's an example event payload:

{
  "check": {
    "name": "Keen IO Web",
    "url": "https://keen.io",
    "frequency": 5,
    "custom": {
      "server_role": "https",
      "is_https": true
    }
  },
  "environment": {
    "rack_env": "production",
    "region": "heroku_us_east",
    "location": "Virginia, US"
  },
  "request": {
    "sent_at": "2013-10-12T00:00:00.000Z",
    "duration": 0.432
  },
  "response": {
    "successful": true,
    "timed_out": false,
    "status": 200,
    "server": "TornadoServer/3.1",
    "http_status": 200,
    "http_reason": "OK",
    "http_version": "1.1",
    "content_type": "text/html",
    "content_length": 175,
    "date": "Wed, 16 Apr 2014 17:39:01 GMT"
  }
}

Here's a breakdown of the major sections:

  • check: properties describing the check, including any custom properties
  • environment: properties describing where the check was made from (useful when you are running Pingpong instances across multiple datacenters)
  • request: information about the HTTP request that was sent
  • response: information about the HTTP response that was recorded

response.timed_out and response.successful are helper properties. response.successful is true if the request did not timeout and the response status is between 100 and 399.

It's easy to add more fields to the environment section in config.yml, or implement a CheckMarshaller component that translates HTTP response fields to properties in a different way.

Capturing all of these fields makes it possible to perform powerful grouping and filtering during analysis.

Reporting and Alerting

Pingpong uses Pushpop to provide basic alerting and reporting functionality. This functionality can easily be extended to create your own custom alerts and reports.

Additional Options & Recipes

Configuration

See config.yml for an idea of what can be configured with settings. Examples include timeouts, pluggable components, and environment properties.

Save a URL's JSON Response Body

If a configured check returns JSON, you can save that JSON into the request body. This allows you to monitor and analyze not only the success or failure of web calls, but also the values they can return.

To save the body, select true when creating a new check.

This example grabs the weather from the Forecast.io API as JSON. The weather data will be merged into the response body under the key response.body. Here's an example check response event (some fields omitted for clarity):

{ 
  "response": {
    "body": {
      "latitude": 37.8267,
      "longitude": -122.423,
      "timezone": "America/Los_Angeles",
      "currently": {
        "temperature": 56.78,
        "summary": "Overcast",
        "icon": "cloudy"
      }
    }
  }
}

Now you can visualize temperature over time by using response.body.currently.temperature as the target property for analysis!

Note: The Content-Type header of the check's response must contain application/json for it to be saved. Otherwise a warning will be logged.

Note #2: To avoid hitting Keen IO limits on the number of properties per event and per collection across all events, JSON response bodies should ideally be small and/or consistent.

Pluggability

Each major component of Pingpong is pluggable:

  • Checks get run by a pushpop job in jobs/run_checks_job.rb
  • CheckMarshaller: transforms a check and its result into the JSON payload to be logged. The efault implementation is EnvironmentAwareCheckMarshaller.
  • CheckLogger: logs the JSON payload from the CheckMarshaller. The default implementation is KeenCheckLogger.

Once you've written an implementation for any of these components, simply replace the previous implementation's class name in config.yml with name of your component.

HTTP Authentication

Set the HTTP_USERNAME and HTTP_PASSWORD environment variables to enable HTTP authentication for the dashboard. Off by default.

Custom Headers

Set the headers property of a check to a hash of headers you'd like included with the request. For example:

{
  "checks": [
    {
      "name": "JSON API Check",
      "url": "http://example.com/api",
      "frequency": 5,
      "headers": { "Accept": "application/json" },
      "method": "GET"
    }
  ]
}

Inspiration

Pingpong was developed in-house at Keen IO to answer a few simple, but important, questions about our web and API infrastructure:

  • Are any API servers or server processes slower than others?
  • Are any web pages or API calls slow? Are any experiencing errors?
  • Have any processes failed, or become unresponsive? Today? This month?
  • What's the latency to each DC from a client in the US? In Europe?
  • How much latency does using SSL add?

Pingpong runs all day, every day from multiple data centers around the world, helping our team understand current performance and study long-term trends. To date, Pingpong has run more than 20 million checks in production.

Helpful Links

Contributing

Contributions are very welcome. Here are some ideas for new features:

Wish List
  • More tabs and queries and visualizations on the dashboard
  • More default alerts
  • Deploy instructions for multiple platforms
  • Ability to merge multiple data centers into one set of graphs
  • Support for more back-ends and front-ends
  • Support for HTTP POST

Pingpong has a full set of specs. Before submitting your pull request, make sure to run them:

$ bundle exec rake spec
Contributors

If you contribute, add your name to this list!

pingpong's People

Contributors

cdwiegand avatar dorkitude avatar gphat avatar heitortsergent avatar hex337 avatar itdrake91 avatar joshed-io avatar lexicography avatar loren avatar nedrocks avatar scarpenter avatar simplyaubs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pingpong's Issues

Install difficult on Ubuntu 14.04

This tool looks great, but the install is difficult. Suggest you fire up a new Ubuntu 14.04 VM, update fully, then give it a shot.

Specifically I had trouble:

  • Installing json gem (got it eventually)
  • Installing eventmachine gem (something to do with OpenSSL I think). This is where I gave up.

I suspect some additional packages are required, but I'm not an ubuntu or Ruby expert.

Error from a referenced error file: package configuration for openssl is not found

Trace of trying to install

bundle install
Don't run Bundler as root. Bundler can ask for sudo if it is needed, and installing your bundle as root will break this
application for all non-root users on this machine.
Fetching gem metadata from http://rubygems.org/...........
Fetching version metadata from http://rubygems.org/.
Resolving dependencies...
Using rake 11.3.0
Using i18n 0.7.0
Using json 1.8.3
Using minitest 5.9.1
Using thread_safe 0.3.5
Using builder 3.2.2
Using arel 6.0.3
Using addressable 2.3.8
Using backports 3.6.8
Using coderay 1.1.1
Using cookiejar 0.3.3
Using safe_yaml 1.0.4
Using diff-lcs 1.2.5
Using dotenv 2.1.1
Installing eventmachine 1.2.0.1 with native extensions
Installing http_parser.rb 0.6.0 with native extensions
Using thor 0.19.1
Using tilt 2.0.5
Using hashdiff 0.3.0
Using multi_xml 0.5.5
Using multi_json 1.12.1
Using mime-types-data 3.2016.0521
Using method_source 0.8.2
Installing pg 0.18.1 with native extensions
Using slop 3.6.0
Using rack 1.6.5
Using slack-notifier 1.5.1
Using rspec-support 3.5.0
Using bundler 1.13.6
Using tzinfo 1.2.2
Using crack 0.4.3
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

current directory: /var/lib/gems/2.3.0/gems/eventmachine-1.2.0.1/ext

/usr/bin/ruby2.3 -r ./siteconf20161116-15126-1aza4q0.rb extconf.rb
checking for main() in -lcrypto... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers. Check the mkmf.log file for more details. You may
need configuration options.

Provided configuration options:
--with-opt-dir
--without-opt-dir
--with-opt-include
--without-opt-include=${opt-dir}/include
--with-opt-lib
--without-opt-lib=${opt-dir}/lib
--with-make-prog
--without-make-prog
--srcdir=.
--curdir
--ruby=/usr/bin/$(RUBY_BASE_NAME)2.3
--with-ssl-dir
--without-ssl-dir
--with-ssl-include
--without-ssl-include=${ssl-dir}/include
--with-ssl-lib
--without-ssl-lib=${ssl-dir}/lib
--with-openssl-config
--without-openssl-config
--with-pkg-config
--without-pkg-config
--with-cryptolib
--without-cryptolib
/usr/lib/ruby/2.3.0/mkmf.rb:456:in try_do': The compiler failed to generate an executable file. (RuntimeError) You have to install development tools first. from /usr/lib/ruby/2.3.0/mkmf.rb:541:in try_link0'
from /usr/lib/ruby/2.3.0/mkmf.rb:556:in try_link' from /usr/lib/ruby/2.3.0/mkmf.rb:765:in try_func'
from /usr/lib/ruby/2.3.0/mkmf.rb:997:in block in have_library' from /usr/lib/ruby/2.3.0/mkmf.rb:942:in block in checking_for'
from /usr/lib/ruby/2.3.0/mkmf.rb:350:in block (2 levels) in postpone' from /usr/lib/ruby/2.3.0/mkmf.rb:320:in open'
from /usr/lib/ruby/2.3.0/mkmf.rb:350:in block in postpone' from /usr/lib/ruby/2.3.0/mkmf.rb:320:in open'
from /usr/lib/ruby/2.3.0/mkmf.rb:346:in postpone' from /usr/lib/ruby/2.3.0/mkmf.rb:941:in checking_for'
from /usr/lib/ruby/2.3.0/mkmf.rb:992:in have_library' from extconf.rb:8:in block in check_libs'
from extconf.rb:8:in each' from extconf.rb:8:in all?'
from extconf.rb:8:in check_libs' from extconf.rb:95:in

'

To see why this extension failed to compile, please check the mkmf.log which can be found here:

/var/lib/gems/2.3.0/extensions/x86_64-linux/2.3.0/eventmachine-1.2.0.1/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /var/lib/gems/2.3.0/gems/eventmachine-1.2.0.1 for inspection.
Results logged to /var/lib/gems/2.3.0/extensions/x86_64-linux/2.3.0/eventmachine-1.2.0.1/gem_make.out

An error occurred while installing eventmachine (1.2.0.1), and Bundler cannot continue.
Make sure that gem install eventmachine -v '1.2.0.1' succeeds before bundling.

Average Response Time Graph blanks

I've deployed to heroku in a standard manner, and I can see data in my keen collection, however my average response time graph is completely blank.

Anything I can do to debug?

For a warn or error check, highlight what caused that state

Right now, on the view check page, when an individual check is shown as red or yellow, there's no indication as to why. We should highlight the relevant info in the check drill down, and add a short phrase about the issue in the compact view.

Check state and latest incident status don't always match

@hex337

Right now the backend (ruby) decides if a check has an active response time incident by comparing the most recent check event with the mean of the past 30 response times.

The frontend (js) decides if a check event should have produced an incident by comparing the most recent check event respones time with the mean of the latest 10 check events in the last 30 minutes.

If your pingpong instance is long-running and hasn't missed a beat, these will always be the same sets of data. However, if Pingpong crashes, you lose data somehow, Keen goes down, etc. these data sets wil;l mismatch. That makes the frontend inconsistent with states.

The solution here is probably to just have the frontend use the mean values generated on the backend - that should be easy to drop in from the check view HAML.

A check should have a save_body param, which if set to true, saves each response into the event as JSON or a string

If the response's content type is JSON, the JSON should be added to the response object under the "results.body" key. If the response's content type is HTML, it should be stored as an opaque string.

For the HTML case, its possible the string could be too large. In that case, we could choose to truncate over a certain size for now.

For the JSON case, the endpoint should be one that returns a document with relatively consistent keys. If the keys are not consistent over time, events will eventually error because the overall number of properties for the collection will be too large.

This would enable not only monitoring health from the HTTP dimensions, but from any dimension the underlying service wishes to expose.

Test Case - What happens when a check both WARNs and BADs

let’s say a check responds with a WARN on response time, but also a BAD on code... what happens? Does the check show up as a WARN or a BAD?

What about the vice versa case?

It seems to me like the outcome is not well defined.. The code doesn't look like it intentionally handles that case.

We should create a test to verify the issue, then fix it if it fails.

Send good (ie: incident ended) notifications

@hex337

Right now the run_checks_job.rb sendgrid and slack steps filter out any incidents that are good - that means you get no notification if an incident ends.

I think that we should at least do a slack notification when incidents end (with a pretty green attachment color).

Don't show faces on the checks until we have the minimum number of checks required

Right now, when looking at an individual check's page, you can see a table view of the last N checks, and each one has a nice looking face next to it.

The first check will always have a red face since we don't have enough information to compute an average. What we SHOULD do, is not show anything for those faces if we haven't hit the min number of checks (which is defined in lib/check.rb).

So, the net result, is no faces until you hit N checks, and then after that, keep doing what its currently doing!

Push to slack integration?

It would be really awesome if pushpop had an extension for slack! It could look just like the sendgrid and twilio functionality, but instead of pushing email/sms it would push a notification to a slack channel via their REST API.

An example POST request looks like this:
curl -X POST --data-urlencode 'payload={"text": "This is posted to <#general> and comes from *monkey-bot*.", "channel": "#general", "username": "monkey-bot", "icon_emoji": ":monkey_face:"}' https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX

https://api.slack.com/incoming-webhooks

Even better, there's a gem for posting to slack!
https://github.com/stevenosloan/slack-notifier

Checks detailed view broken for objects

Right now, the detailed view for a check doesn't work properly custom properties and data attributes.

We want this to display correctly, even when its empty.

Clean up old incidents

We want to limit the number of DB rows incidents take up, so we should clear out old ones that we no longer need.

Not sure what the right amount to keep is, but probably no need to keep anything more than the last 100.

Don't alert on first response time spike

Right now, we raise the alarms when a single request is slower than expected.

What we should do is be smarter about it. If there is a single spike in response time, that should be OK. If we get two slow responses in a row, we should worry about it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.